kernel32: Make event/mutex/semaphore functions hotpatchable.
[wine] / dlls / commdlg.dll16 / finddlg.c
1 /*
2  * COMMDLG - 16 bits Find & Replace Text Dialogs
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1996 Albrecht Kleine
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <ctype.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wine/winbase16.h"
29 #include "wine/winuser16.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "commdlg.h"
33 #include "cderr.h"
34 #include "cdlg16.h"
35
36
37
38 /***********************************************************************
39  *                              FINDDLG_WMInitDialog            [internal]
40  */
41 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, LPARAM lParam, LPDWORD lpFlags,
42                                     LPCSTR lpstrFindWhat)
43 {
44     SetWindowLongPtrW(hWnd, DWLP_USER, lParam);
45     *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
46     /*
47      * FIXME : If the initial FindWhat string is empty, we should disable the
48      * FindNext (IDOK) button.  Only after typing some text, the button should be
49      * enabled.
50      */
51     SetDlgItemTextA(hWnd, edt1, lpstrFindWhat);
52     CheckRadioButton(hWnd, rad1, rad2, (*lpFlags & FR_DOWN) ? rad2 : rad1);
53     if (*lpFlags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
54         EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
55         EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
56     }
57     if (*lpFlags & FR_HIDEUPDOWN) {
58         ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
59         ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
60         ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
61     }
62     CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
63     if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
64         EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
65     if (*lpFlags & FR_HIDEWHOLEWORD)
66         ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
67     CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
68     if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
69         EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
70     if (*lpFlags & FR_HIDEMATCHCASE)
71         ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
72     if (!(*lpFlags & FR_SHOWHELP)) {
73         EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
74         ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
75     }
76     ShowWindow(hWnd, SW_SHOWNORMAL);
77     return TRUE;
78 }
79
80
81 /***********************************************************************
82  *                              FINDDLG_WMCommand               [internal]
83  */
84 static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam,
85                                  HWND hwndOwner, LPDWORD lpFlags,
86                                  LPSTR lpstrFindWhat, WORD wFindWhatLen)
87 {
88     int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA );
89     int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA );
90
91     switch (LOWORD(wParam)) {
92         case IDOK:
93             GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
94             if (IsDlgButtonChecked(hWnd, rad2))
95                 *lpFlags |= FR_DOWN;
96                 else *lpFlags &= ~FR_DOWN;
97             if (IsDlgButtonChecked(hWnd, chx1))
98                 *lpFlags |= FR_WHOLEWORD;
99                 else *lpFlags &= ~FR_WHOLEWORD;
100             if (IsDlgButtonChecked(hWnd, chx2))
101                 *lpFlags |= FR_MATCHCASE;
102                 else *lpFlags &= ~FR_MATCHCASE;
103             *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
104             *lpFlags |= FR_FINDNEXT;
105             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
106                           GetWindowLongPtrW(hWnd, DWLP_USER) );
107             return TRUE;
108         case IDCANCEL:
109             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
110             *lpFlags |= FR_DIALOGTERM;
111             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
112                           GetWindowLongPtrW(hWnd, DWLP_USER) );
113             DestroyWindow(hWnd);
114             return TRUE;
115         case pshHelp:
116             /* FIXME : should lpfr structure be passed as an argument ??? */
117             SendMessageA(hwndOwner, uHelpMessage, 0, 0);
118             return TRUE;
119     }
120     return FALSE;
121 }
122
123
124 /***********************************************************************
125  *           find_text_dlgproc   (internal)
126  */
127 static INT_PTR CALLBACK find_text_dlgproc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
128 {
129     LPFINDREPLACE16 lpfr;
130     switch (wMsg)
131     {
132         case WM_INITDIALOG:
133             lpfr=MapSL(lParam);
134             return FINDDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags, MapSL(lpfr->lpstrFindWhat));
135         case WM_COMMAND:
136             lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER));
137             return FINDDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner),
138                 &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),
139                 lpfr->wFindWhatLen);
140     }
141     return FALSE;
142 }
143
144
145 /***********************************************************************
146  *           FindText   (COMMDLG.11)
147  */
148 HWND16 WINAPI FindText16( SEGPTR find )
149 {
150     FINDREPLACE16 *fr16 = MapSL( find );
151
152     return HWND_16( CreateDialogParamA( GetModuleHandleA("comdlg32.dll"), MAKEINTRESOURCEA(FINDDLGORD),
153                                         HWND_32(fr16->hwndOwner), find_text_dlgproc, find ));
154 }
155
156
157 /***********************************************************************
158  *           FindTextDlgProc   (COMMDLG.13)
159  */
160 BOOL16 CALLBACK FindTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
161                                  LPARAM lParam)
162 {
163     return find_text_dlgproc( HWND_32(hWnd16), wMsg, wParam, lParam );
164 }
165
166
167 /***********************************************************************
168  *                              REPLACEDLG_WMInitDialog         [internal]
169  */
170 static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, LPARAM lParam,
171                     LPDWORD lpFlags, LPCSTR lpstrFindWhat,
172                     LPCSTR lpstrReplaceWith)
173 {
174     SetWindowLongPtrW(hWnd, DWLP_USER, lParam);
175     *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
176     /*
177      * FIXME : If the initial FindWhat string is empty, we should disable the FindNext /
178      * Replace / ReplaceAll buttons.  Only after typing some text, the buttons should be
179      * enabled.
180      */
181     SetDlgItemTextA(hWnd, edt1, lpstrFindWhat);
182     SetDlgItemTextA(hWnd, edt2, lpstrReplaceWith);
183     CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
184     if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
185         EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
186     if (*lpFlags & FR_HIDEWHOLEWORD)
187         ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
188     CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
189     if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
190         EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
191     if (*lpFlags & FR_HIDEMATCHCASE)
192         ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
193     if (!(*lpFlags & FR_SHOWHELP)) {
194         EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
195         ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
196     }
197     ShowWindow(hWnd, SW_SHOWNORMAL);
198     return TRUE;
199 }
200
201
202 /***********************************************************************
203  *                              REPLACEDLG_WMCommand            [internal]
204  */
205 static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM wParam,
206                                     HWND hwndOwner, LPDWORD lpFlags,
207                                     LPSTR lpstrFindWhat, WORD wFindWhatLen,
208                                     LPSTR lpstrReplaceWith, WORD wReplaceWithLen)
209 {
210     int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA );
211     int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA );
212
213     switch (LOWORD(wParam)) {
214         case IDOK:
215             GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
216             GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
217             if (IsDlgButtonChecked(hWnd, chx1))
218                 *lpFlags |= FR_WHOLEWORD;
219                 else *lpFlags &= ~FR_WHOLEWORD;
220             if (IsDlgButtonChecked(hWnd, chx2))
221                 *lpFlags |= FR_MATCHCASE;
222                 else *lpFlags &= ~FR_MATCHCASE;
223             *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
224             *lpFlags |= FR_FINDNEXT;
225             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
226                           GetWindowLongPtrW(hWnd, DWLP_USER) );
227             return TRUE;
228         case IDCANCEL:
229             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
230             *lpFlags |= FR_DIALOGTERM;
231             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
232                           GetWindowLongPtrW(hWnd, DWLP_USER) );
233             DestroyWindow(hWnd);
234             return TRUE;
235         case psh1:
236             GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
237             GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
238             if (IsDlgButtonChecked(hWnd, chx1))
239                 *lpFlags |= FR_WHOLEWORD;
240                 else *lpFlags &= ~FR_WHOLEWORD;
241             if (IsDlgButtonChecked(hWnd, chx2))
242                 *lpFlags |= FR_MATCHCASE;
243                 else *lpFlags &= ~FR_MATCHCASE;
244             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
245             *lpFlags |= FR_REPLACE;
246             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
247                           GetWindowLongPtrW(hWnd, DWLP_USER) );
248             return TRUE;
249         case psh2:
250             GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
251             GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
252             if (IsDlgButtonChecked(hWnd, chx1))
253                 *lpFlags |= FR_WHOLEWORD;
254                 else *lpFlags &= ~FR_WHOLEWORD;
255             if (IsDlgButtonChecked(hWnd, chx2))
256                 *lpFlags |= FR_MATCHCASE;
257                 else *lpFlags &= ~FR_MATCHCASE;
258             *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
259             *lpFlags |= FR_REPLACEALL;
260             SendMessageW( hwndOwner, uFindReplaceMessage, 0,
261                           GetWindowLongPtrW(hWnd, DWLP_USER) );
262             return TRUE;
263         case pshHelp:
264             /* FIXME : should lpfr structure be passed as an argument ??? */
265             SendMessageA(hwndOwner, uHelpMessage, 0, 0);
266             return TRUE;
267     }
268     return FALSE;
269 }
270
271
272 /***********************************************************************
273  *           replace_text_dlgproc
274  */
275 static INT_PTR CALLBACK replace_text_dlgproc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
276 {
277     LPFINDREPLACE16 lpfr;
278     switch (wMsg)
279     {
280         case WM_INITDIALOG:
281             lpfr=MapSL(lParam);
282             return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags,
283                     MapSL(lpfr->lpstrFindWhat),
284                     MapSL(lpfr->lpstrReplaceWith));
285         case WM_COMMAND:
286             lpfr=MapSL(GetWindowLongPtrW(hWnd, DWLP_USER));
287             return REPLACEDLG_WMCommand(hWnd, wParam, HWND_32(lpfr->hwndOwner),
288                     &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),
289                     lpfr->wFindWhatLen, MapSL(lpfr->lpstrReplaceWith),
290                     lpfr->wReplaceWithLen);
291     }
292     return FALSE;
293 }
294
295
296 /***********************************************************************
297  *           ReplaceText   (COMMDLG.12)
298  */
299 HWND16 WINAPI ReplaceText16( SEGPTR find )
300 {
301     FINDREPLACE16 *fr16 = MapSL( find );
302
303     return HWND_16( CreateDialogParamA( GetModuleHandleA("comdlg32.dll"), MAKEINTRESOURCEA(REPLACEDLGORD),
304                                         HWND_32(fr16->hwndOwner), replace_text_dlgproc, find ));
305 }
306
307
308 /***********************************************************************
309  *           ReplaceTextDlgProc   (COMMDLG.14)
310  */
311 BOOL16 CALLBACK ReplaceTextDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
312                                     LPARAM lParam)
313 {
314     return replace_text_dlgproc( HWND_32(hWnd16), wMsg, wParam, lParam );
315 }
316
317
318 /***********************************************************************
319  *      CommDlgExtendedError                    (COMMDLG.26)
320  */
321 DWORD WINAPI CommDlgExtendedError16(void)
322 {
323     return CommDlgExtendedError();
324 }