Subversion Repositories filter_foundry

Rev

Rev 460 | Rev 463 | 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
 
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
 
460 daniel-mar 100
LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
101
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
102
}
103
 
461 daniel-mar 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
 
444 daniel-mar 126
Boolean MakeSimpleSubclass(LPCTSTR targetClass, LPCTSTR sourceClass) {
439 daniel-mar 127
        WNDCLASS clx;
128
 
444 daniel-mar 129
        if (GetClassInfo(hDllInstance, sourceClass, &clx) != 0) {
439 daniel-mar 130
                clx.lpszClassName = targetClass;
131
                if (RegisterClass(&clx) == 0) {
444 daniel-mar 132
                        TCHAR s[0x300];
133
                        xstrcpy(s, (TCHAR*)TEXT("RegisterClass failed: "));
454 daniel-mar 134
                        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + xstrlen(s), 0x300 - (DWORD)xstrlen(s), NULL);
444 daniel-mar 135
                        dbg(&s[0]);
439 daniel-mar 136
                        return false;
137
                }
138
                else {
139
                        return true;
140
                }
141
        }
142
        else {
460 daniel-mar 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(TEXT("GetClassInfo failed"));
170
                }
439 daniel-mar 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
 
444 daniel-mar 182
        if (GetClassInfo(hDllInstance, TEXT("slider"), &clx) != 0) {
439 daniel-mar 183
                UnregisterSlider(hDllInstance);
184
        }
185
        if (gdata->pluginDllModule) {
186
                FreeLibrary(gdata->pluginDllModule);
187
                gdata->pluginDllModule = 0;
188
        }
189
#endif
190
 
191
}
192
 
444 daniel-mar 193
Boolean Slider_Init_PluginDll(LPCTSTR targetClass) {
439 daniel-mar 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"
444 daniel-mar 201
        gdata->pluginDllModule = LoadLibrary(TEXT("PLUGIN.DLL"));
439 daniel-mar 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
444 daniel-mar 215
        return MakeSimpleSubclass(targetClass, TEXT("slider"));
439 daniel-mar 216
#endif
217
 
218
}
219
 
220
typedef void(__stdcall* f_InitCommonControls)();
221
typedef BOOL(__stdcall* f_InitCommonControlsEx)(const INITCOMMONCONTROLSEX* picce);
444 daniel-mar 222
Boolean Slider_Init_MsTrackbar(LPCTSTR targetClass) {
439 daniel-mar 223
        f_InitCommonControls fInitCommonControls;
224
        f_InitCommonControlsEx fInitCommonControlsEx;
225
        HMODULE libComctl32;
226
 
227
        // Make sure that Comctl32 is loaded
444 daniel-mar 228
        libComctl32 = LoadLibrary(TEXT("Comctl32.dll"));
439 daniel-mar 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
444 daniel-mar 252
        return MakeSimpleSubclass(targetClass, TEXT("msctls_trackbar32"));
439 daniel-mar 253
}
254
 
444 daniel-mar 255
Boolean Slider_Init_None(LPCTSTR targetClass) {
439 daniel-mar 256
        // Make "FoundrySlider" a subclass of "STATIC" (making it invisible)
460 daniel-mar 257
        return MakeSimpleSubclass(targetClass, WC_STATIC);
439 daniel-mar 258
}