Subversion Repositories filter_foundry

Rev

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