Subversion Repositories filter_foundry

Rev

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

Rev Author Line No. Line
439 daniel-mar 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"
443 daniel-mar 22
#include "slider_win.h"
439 daniel-mar 23
 
470 daniel-mar 24
// More information about the PLUGIN.DLL sliders:
25
// https://misc.daniel-marschall.de/projects/filter_factory/sliders.html
26
 
439 daniel-mar 27
// PLUGIN.DLL Sliders: This method will register the "slider" class used in dialogs.
469 daniel-mar 28
typedef BOOL(__cdecl* f_RegisterSlider)(HINSTANCE hInstanceDll, DWORD* MessageID);
29
BOOL RegisterSlider(HINSTANCE hInstanceDll, DWORD* MessageID) {
439 daniel-mar 30
        f_RegisterSlider fRegisterSlider;
470 daniel-mar 31
        HMODULE hPlugin;
32
        BOOL res;
439 daniel-mar 33
 
470 daniel-mar 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;
439 daniel-mar 40
}
41
 
42
// PLUGIN.DLL Sliders: This method will unregister the "slider" class used in dialogs.
469 daniel-mar 43
typedef BOOL(__cdecl* f_UnregisterSlider)(HINSTANCE hInstanceDll);
44
BOOL UnregisterSlider(HINSTANCE hInstanceDll) {
439 daniel-mar 45
        f_UnregisterSlider fUnregisterSlider;
470 daniel-mar 46
        HMODULE hPlugin;
47
        BOOL res;
439 daniel-mar 48
 
470 daniel-mar 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;
439 daniel-mar 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;
470 daniel-mar 61
        HMODULE hPlugin;
62
        int res;
439 daniel-mar 63
 
470 daniel-mar 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;
439 daniel-mar 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;
470 daniel-mar 76
        HMODULE hPlugin;
77
        int res;
439 daniel-mar 78
 
470 daniel-mar 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;
439 daniel-mar 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;
470 daniel-mar 91
        HMODULE hPlugin;
92
        int res;
439 daniel-mar 93
 
470 daniel-mar 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;
439 daniel-mar 100
}
101
 
460 daniel-mar 102
LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
103
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
104
}
105
 
461 daniel-mar 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
 
444 daniel-mar 128
Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass) {
439 daniel-mar 129
        WNDCLASS clx;
130
 
444 daniel-mar 131
        if (GetClassInfo(hDllInstance, sourceClass, &clx) != 0) {
439 daniel-mar 132
                clx.lpszClassName = targetClass;
133
                if (RegisterClass(&clx) == 0) {
444 daniel-mar 134
                        TCHAR s[0x300];
135
                        xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
454 daniel-mar 136
                        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
444 daniel-mar 137
                        dbg(&s[0]);
439 daniel-mar 138
                        return false;
139
                }
140
                else {
141
                        return true;
142
                }
143
        }
144
        else {
460 daniel-mar 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 {
463 daniel-mar 171
                        simplealert((TCHAR*)TEXT("GetClassInfo failed"));
460 daniel-mar 172
                }
439 daniel-mar 173
                return false;
174
        }
175
}
176
 
177
void Slider_Uninit_PluginDll() {
178
#ifndef use_plugin_dll_sliders
179
        return;
180
#else
470 daniel-mar 181
        if (gdata->pluginDllSliderInitialized) {
182
                if (UnregisterSlider(hDllInstance)) {
183
                        gdata->pluginDllSliderInitialized = false;
184
                } else {
185
                        simplealert(TEXT("UnRegisterSlider failed"));
186
                }
439 daniel-mar 187
        }
188
#endif
189
 
190
}
191
 
444 daniel-mar 192
Boolean Slider_Init_PluginDll(LPCTSTR targetClass) {
439 daniel-mar 193
 
194
#ifndef use_plugin_dll_sliders
195
        return false;
196
#else
470 daniel-mar 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
469 daniel-mar 203
        }
204
 
439 daniel-mar 205
        // Make "FoundrySlider" a subclass of "slider" then
444 daniel-mar 206
        return MakeSimpleSubclass(targetClass, TEXT("slider"));
439 daniel-mar 207
#endif
208
 
209
}
210
 
211
typedef void(__stdcall* f_InitCommonControls)();
212
typedef BOOL(__stdcall* f_InitCommonControlsEx)(const INITCOMMONCONTROLSEX* picce);
444 daniel-mar 213
Boolean Slider_Init_MsTrackbar(LPCTSTR targetClass) {
439 daniel-mar 214
        f_InitCommonControls fInitCommonControls;
215
        f_InitCommonControlsEx fInitCommonControlsEx;
216
        HMODULE libComctl32;
217
 
218
        // Make sure that Comctl32 is loaded
444 daniel-mar 219
        libComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
439 daniel-mar 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
444 daniel-mar 243
        return MakeSimpleSubclass(targetClass, TEXT("msctls_trackbar32"));
439 daniel-mar 244
}
245
 
444 daniel-mar 246
Boolean Slider_Init_None(LPCTSTR targetClass) {
439 daniel-mar 247
        // Make "FoundrySlider" a subclass of "STATIC" (making it invisible)
460 daniel-mar 248
        return MakeSimpleSubclass(targetClass, WC_STATIC);
439 daniel-mar 249
}