Subversion Repositories filter_foundry

Rev

Rev 471 | Rev 477 | 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.         BOOL res;
  32.  
  33.         if (!gdata->libPluginDll) return false;
  34.         fRegisterSlider = (f_RegisterSlider)(void*)GetProcAddress(gdata->libPluginDll, "RegisterSlider");
  35.         res = (fRegisterSlider != 0) ? fRegisterSlider(hInstanceDll, MessageID) : false;
  36.         return res;
  37. }
  38.  
  39. // PLUGIN.DLL Sliders: This method will unregister the "slider" class used in dialogs.
  40. typedef BOOL(__cdecl* f_UnRegisterSlider)(HINSTANCE hInstanceDll);
  41. BOOL UnRegisterSlider(HINSTANCE hInstanceDll) {
  42.         f_UnRegisterSlider fUnRegisterSlider;
  43.         BOOL res;
  44.  
  45.         if (!gdata->libPluginDll) return false;
  46.         fUnRegisterSlider = (f_UnRegisterSlider)(void*)GetProcAddress(gdata->libPluginDll, "UnRegisterSlider");
  47.         res = (fUnRegisterSlider != 0) ? fUnRegisterSlider(hInstanceDll) : false;
  48.         return res;
  49. }
  50.  
  51. // PLUGIN.DLL Sliders: Set slider range (min/max)
  52. typedef int(__cdecl* f_SetSliderRange)(HWND hWnd, int nMin, int nMax);
  53. int SetSliderRange(HWND hWnd, int nMin, int nMax) {
  54.         f_SetSliderRange fSetSliderRange;
  55.         int res;
  56.  
  57.         if (!gdata->libPluginDll) return 0;
  58.         fSetSliderRange = (f_SetSliderRange)(void*)GetProcAddress(gdata->libPluginDll, "SetSliderRange");
  59.         res = (fSetSliderRange != 0) ? fSetSliderRange(hWnd, nMin, nMax) : 0;
  60.         return res;
  61. }
  62.  
  63. // PLUGIN.DLL Sliders : Sets slider position
  64. typedef int(__cdecl* f_SetSliderPos)(HWND hWnd, int nPos, BOOL bRepaint);
  65. int SetSliderPos(HWND hWnd, int nPos, BOOL bRepaint) {
  66.         f_SetSliderPos fSetSliderPos;
  67.         int res;
  68.  
  69.         if (!gdata->libPluginDll) return 0;
  70.         fSetSliderPos = (f_SetSliderPos)(void*)GetProcAddress(gdata->libPluginDll, "SetSliderPos");
  71.         res = (fSetSliderPos != 0) ? fSetSliderPos(hWnd, nPos, bRepaint) : 0;
  72.         return res;
  73. }
  74.  
  75. // PLUGIN.DLL Sliders : Get slider position
  76. typedef int(__cdecl* f_GetSliderPos)(HWND hWnd, BOOL bPixelPosition);
  77. int GetSliderPos(HWND hWnd, BOOL bPixelPosition) {
  78.         f_GetSliderPos fGetSliderPos;
  79.         int res;
  80.  
  81.         if (!gdata->libPluginDll) return 0;
  82.         fGetSliderPos = (f_GetSliderPos)(void*)GetProcAddress(gdata->libPluginDll, "GetSliderPos");
  83.         res = (fGetSliderPos != 0) ? fGetSliderPos(hWnd, bPixelPosition) : 0;
  84.         return res;
  85. }
  86.  
  87. LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  88.         return DefWindowProc(hwnd, uMsg, wParam, lParam);
  89. }
  90.  
  91. void Win32sFixSuperclassing(HWND hDlg, int destItem, int sourceItem) {
  92.         // Win32s (Win3.11) compatibility fix: Since GetClassInfo(WC_BUTTON) and GetClassInfo(WC_STATIC) won't work,
  93.         // we had replaced the WndProc by a dummy. Now, we find out the real Button and Static WndProcs and give them
  94.         // to our classes, making them the intended superclasses. Messages which have been sent in between were lost,
  95.         // though...
  96.  
  97.         WNDPROC wndProc;
  98. #ifdef _WIN64
  99.         wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC);
  100.         if (wndProc == DummyWndProc) {
  101.                 wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWLP_WNDPROC);
  102.                 SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWLP_WNDPROC, (LONG_PTR)wndProc);
  103.         }
  104. #else
  105.         wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC);
  106.         if (wndProc == DummyWndProc) {
  107.                 wndProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hDlg, sourceItem), GWL_WNDPROC);
  108.                 SetWindowLongPtr(GetDlgItem(hDlg, destItem), GWL_WNDPROC, (LONG_PTR)wndProc);
  109.         }
  110. #endif
  111. }
  112.  
  113. Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass) {
  114.         WNDCLASS clx;
  115.  
  116.         if (GetClassInfo(hDllInstance, sourceClass, &clx) != 0) {
  117.                 clx.lpszClassName = targetClass;
  118.                 if (RegisterClass(&clx) == 0) {
  119.                         TCHAR s[0x300];
  120.                         xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
  121.                         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
  122.                         dbg(&s[0]);
  123.                         return false;
  124.                 }
  125.                 else {
  126.                         return true;
  127.                 }
  128.         }
  129.         else {
  130.                 if ((xstrcmp(sourceClass, WC_BUTTON) == 0) || (xstrcmp(sourceClass, WC_STATIC) == 0)) {
  131.                         // GetClassInfo(WC_STATIC) and GetClassInfo(WC_BUTTON) fail on Win32s (Windows 3.11)
  132.                         // So we create a fake-class now. It will be replaced with the real Button/Static WndProc later!
  133.                         clx.style = 0;
  134.                         clx.lpfnWndProc = DummyWndProc;
  135.                         clx.cbClsExtra = 0;
  136.                         clx.cbWndExtra = 0;
  137.                         clx.hInstance = hDllInstance;
  138.                         clx.hIcon = 0;
  139.                         clx.hCursor = 0;
  140.                         clx.hbrBackground = 0;
  141.                         clx.lpszMenuName = 0;
  142.                         clx.lpszClassName = targetClass;
  143.  
  144.                         if (RegisterClass(&clx) == 0) {
  145.                                 TCHAR s[0x300];
  146.                                 xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
  147.                                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
  148.                                 dbg(&s[0]);
  149.                                 return false;
  150.                         }
  151.                         else {
  152.                                 return true;
  153.                         }
  154.                 }
  155.                 else {
  156.                         simplealert((TCHAR*)TEXT("GetClassInfo failed"));
  157.                 }
  158.                 return false;
  159.         }
  160. }
  161.  
  162. Boolean Slider_Init_PluginDll(LPCTSTR targetClass) {
  163.  
  164. #ifndef use_plugin_dll_sliders
  165.         return false;
  166. #else
  167.         if (gdata->pluginDllSliderInitialized) return true;
  168.  
  169.         if (!gdata->libPluginDll) {
  170.                 // DM 16.04.2022 : It is important that PLUGIN.DLL stays loaded, otherwise
  171.                 // DialogBoxParamA crashes. Can be reproduced if all 8BX modules are disabled in Photoshop 7
  172.                 // (they keep PLUGIN.DLL loaded).
  173.                 gdata->libPluginDll = LoadLibrary(TEXT("Plugin.dll"));
  174.         }
  175.  
  176.         if (gdata->libPluginDll && RegisterSlider(hDllInstance, &gdata->pluginDllSliderMessageId)) {
  177.                 gdata->pluginDllSliderInitialized = true;
  178.  
  179.                 // Make "FoundrySlider" a subclass of "slider" then
  180.                 return MakeSimpleSubclass(targetClass, TEXT("slider"));
  181.         }
  182.         else {
  183.                 // This can happen if PLUGIN.DLL is not existing
  184.                 // It will also happen if a previous uninitialization failed (or was forgotten)
  185.                 return false; // Fall back to Windows sliders
  186.         }
  187. #endif
  188.  
  189. }
  190.  
  191. void Slider_Uninit_PluginDll() {
  192. #ifndef use_plugin_dll_sliders
  193.         return;
  194. #else
  195.         if (gdata->pluginDllSliderInitialized) {
  196.                 if (UnRegisterSlider(hDllInstance)) {
  197.                         gdata->pluginDllSliderInitialized = false;
  198.  
  199.                         if (gdata->libPluginDll) {
  200.                                 FreeLibrary(gdata->libPluginDll);
  201.                                 gdata->libPluginDll = 0;
  202.                         }
  203.                 }
  204.                 else {
  205.                         simplealert((TCHAR*)TEXT("UnRegisterSlider failed"));
  206.                 }
  207.         }
  208. #endif
  209.  
  210. }
  211.  
  212. typedef void(__stdcall* f_InitCommonControls)();
  213. typedef BOOL(__stdcall* f_InitCommonControlsEx)(const INITCOMMONCONTROLSEX* picce);
  214. Boolean Slider_Init_MsTrackbar(LPCTSTR targetClass) {
  215.         f_InitCommonControls fInitCommonControls;
  216.         f_InitCommonControlsEx fInitCommonControlsEx;
  217.  
  218.         // Make sure that Comctl32 is loaded
  219.         if (!gdata->libComctl32) {
  220.                 gdata->libComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
  221.         }
  222.         if (gdata->libComctl32) {
  223.                 fInitCommonControlsEx = (f_InitCommonControlsEx)(void*)GetProcAddress(gdata->libComctl32, "InitCommonControlsEx");
  224.                 if (fInitCommonControlsEx != 0) {
  225.                         INITCOMMONCONTROLSEX icce;
  226.                         icce.dwSize = sizeof(INITCOMMONCONTROLSEX);
  227.                         icce.dwICC = ICC_BAR_CLASSES;
  228.                         fInitCommonControlsEx(&icce);
  229.                 }
  230.                 else {
  231.                         fInitCommonControls = (f_InitCommonControls)(void*)GetProcAddress(gdata->libComctl32, "InitCommonControls");
  232.                         if (fInitCommonControls != 0) {
  233.                                 fInitCommonControls();
  234.                         }
  235.                 }
  236.  
  237.                 // Make "FoundrySlider" a subclass of "msctls_trackbar32" then
  238.                 return MakeSimpleSubclass(targetClass, TEXT("msctls_trackbar32"));
  239.         }
  240.         else {
  241.                 return false;
  242.         }
  243. }
  244.  
  245. void Slider_Uninit_MsTrackbar() {
  246.         if (gdata->libComctl32 != 0) {
  247.                 FreeLibrary(gdata->libComctl32);
  248.                 gdata->libComctl32 = 0;
  249.         }
  250. }
  251.  
  252. Boolean Slider_Init_None(LPCTSTR targetClass) {
  253.         // Make "FoundrySlider" a subclass of "STATIC" (making it invisible)
  254.         return MakeSimpleSubclass(targetClass, WC_STATIC);
  255. }
  256.  
  257. void Slider_Uninit_None() {
  258.         // Nothing here
  259. }