2 * COMMDLG - 16 bits Find & Replace Text Dialogs
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
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.
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.
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
28 #include "wine/winbase16.h"
29 #include "wine/winuser16.h"
33 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(commdlg
);
43 HANDLE16 hDlgTmpl16
; /* handle for resource 16 */
44 HANDLE16 hResource16
; /* handle for allocated resource 16 */
45 HANDLE16 hGlobal16
; /* 16 bits mem block (resources) */
46 LPCVOID
template; /* template for 32 bits resource */
47 BOOL find
; /* TRUE if find dialog, FALSE if replace dialog */
51 #define LFRPRIVATE struct FRPRIVATE *
53 BOOL16 CALLBACK
FindTextDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
55 BOOL16 CALLBACK
ReplaceTextDlgProc16(HWND16 hWnd
, UINT16 wMsg
, WPARAM16 wParam
,
58 /***********************************************************************
59 * FINDDLG_Get16BitsTemplate [internal]
61 * Get a template (FALSE if failure) when 16 bits dialogs are used
62 * by a 16 bits application
63 * FIXME : no test was done for the user-provided template cases
65 static BOOL
FINDDLG_Get16BitsTemplate(LFRPRIVATE lfr
)
67 LPFINDREPLACE16 fr16
= lfr
->fr16
;
69 if (fr16
->Flags
& FR_ENABLETEMPLATEHANDLE
)
71 lfr
->template = GlobalLock16(fr16
->hInstance
);
74 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE
);
78 else if (fr16
->Flags
& FR_ENABLETEMPLATE
)
81 if (!(hResInfo
= FindResource16(fr16
->hInstance
,
82 MapSL(fr16
->lpTemplateName
),
85 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
88 if (!(lfr
->hDlgTmpl16
= LoadResource16( fr16
->hInstance
, hResInfo
)))
90 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
93 lfr
->hResource16
= lfr
->hDlgTmpl16
;
94 lfr
->template = LockResource16(lfr
->hResource16
);
97 FreeResource16(lfr
->hResource16
);
98 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE
);
103 { /* get resource from (32 bits) own Wine resource; convert it to 16 */
110 if (!(hResInfo
= FindResourceA(COMDLG32_hInstance
,
112 MAKEINTRESOURCEA(FINDDLGORD
):MAKEINTRESOURCEA(REPLACEDLGORD
),
115 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE
);
118 if (!(hDlgTmpl32
= LoadResource(COMDLG32_hInstance
, hResInfo
)) ||
119 !(template32
= LockResource( hDlgTmpl32
)))
121 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE
);
124 size
= SizeofResource(COMDLG32_hInstance
, hResInfo
);
125 hGlobal16
= GlobalAlloc16(0, size
);
128 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE
);
129 ERR("alloc failure for %d bytes\n", size
);
132 lfr
->template = GlobalLock16(hGlobal16
);
135 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE
);
136 ERR("global lock failure for %x handle\n", hGlobal16
);
137 GlobalFree16(hGlobal16
);
140 ConvertDialog32To16(template32
, size
, (LPVOID
)lfr
->template);
141 lfr
->hDlgTmpl16
= hGlobal16
;
142 lfr
->hGlobal16
= hGlobal16
;
148 /***********************************************************************
149 * FINDDLG_FreeResources [internal]
151 * Free resources allocated
153 static void FINDDLG_FreeResources(LFRPRIVATE lfr
)
156 if (lfr
->fr16
->Flags
& FR_ENABLETEMPLATEHANDLE
)
157 GlobalUnlock16(lfr
->fr16
->hInstance
);
158 if (lfr
->hResource16
)
160 GlobalUnlock16(lfr
->hResource16
);
161 FreeResource16(lfr
->hResource16
);
165 GlobalUnlock16(lfr
->hGlobal16
);
166 GlobalFree16(lfr
->hGlobal16
);
170 /***********************************************************************
171 * FindText (COMMDLG.11)
173 HWND16 WINAPI
FindText16( SEGPTR find
)
178 LFRPRIVATE lfr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct FRPRIVATE
));
181 lfr
->fr16
= MapSL(find
);
183 if (FINDDLG_Get16BitsTemplate(lfr
))
185 hInst
= GetWindowLongPtrA( HWND_32(lfr
->fr16
->hwndOwner
), GWLP_HINSTANCE
);
186 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 13);
187 ret
= CreateDialogIndirectParam16( hInst
, lfr
->template,
188 lfr
->fr16
->hwndOwner
, (DLGPROC16
) ptr
, find
);
189 FINDDLG_FreeResources(lfr
);
191 HeapFree(GetProcessHeap(), 0, lfr
);
196 /***********************************************************************
197 * ReplaceText (COMMDLG.12)
199 HWND16 WINAPI
ReplaceText16( SEGPTR find
)
204 LFRPRIVATE lfr
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(struct FRPRIVATE
));
208 * FIXME : We should do error checking on the lpFind structure here
209 * and make CommDlgExtendedError() return the error condition.
211 lfr
->fr16
= MapSL(find
);
213 if (FINDDLG_Get16BitsTemplate(lfr
))
215 hInst
= GetWindowLongPtrA( HWND_32(lfr
->fr16
->hwndOwner
), GWLP_HINSTANCE
);
216 ptr
= GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR
) 14);
217 ret
= CreateDialogIndirectParam16( hInst
, lfr
->template,
218 lfr
->fr16
->hwndOwner
, (DLGPROC16
) ptr
, find
);
220 FINDDLG_FreeResources(lfr
);
222 HeapFree(GetProcessHeap(), 0, lfr
);
227 /***********************************************************************
228 * FINDDLG_WMInitDialog [internal]
230 static LRESULT
FINDDLG_WMInitDialog(HWND hWnd
, LPARAM lParam
, LPDWORD lpFlags
,
231 LPCSTR lpstrFindWhat
, BOOL fUnicode
)
233 SetWindowLongPtrW(hWnd
, DWLP_USER
, lParam
);
234 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACE
| FR_REPLACEALL
| FR_DIALOGTERM
);
236 * FIXME : If the initial FindWhat string is empty, we should disable the
237 * FindNext (IDOK) button. Only after typing some text, the button should be
240 if (fUnicode
) SetDlgItemTextW(hWnd
, edt1
, (LPCWSTR
)lpstrFindWhat
);
241 else SetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
);
242 CheckRadioButton(hWnd
, rad1
, rad2
, (*lpFlags
& FR_DOWN
) ? rad2
: rad1
);
243 if (*lpFlags
& (FR_HIDEUPDOWN
| FR_NOUPDOWN
)) {
244 EnableWindow(GetDlgItem(hWnd
, rad1
), FALSE
);
245 EnableWindow(GetDlgItem(hWnd
, rad2
), FALSE
);
247 if (*lpFlags
& FR_HIDEUPDOWN
) {
248 ShowWindow(GetDlgItem(hWnd
, rad1
), SW_HIDE
);
249 ShowWindow(GetDlgItem(hWnd
, rad2
), SW_HIDE
);
250 ShowWindow(GetDlgItem(hWnd
, grp1
), SW_HIDE
);
252 CheckDlgButton(hWnd
, chx1
, (*lpFlags
& FR_WHOLEWORD
) ? 1 : 0);
253 if (*lpFlags
& (FR_HIDEWHOLEWORD
| FR_NOWHOLEWORD
))
254 EnableWindow(GetDlgItem(hWnd
, chx1
), FALSE
);
255 if (*lpFlags
& FR_HIDEWHOLEWORD
)
256 ShowWindow(GetDlgItem(hWnd
, chx1
), SW_HIDE
);
257 CheckDlgButton(hWnd
, chx2
, (*lpFlags
& FR_MATCHCASE
) ? 1 : 0);
258 if (*lpFlags
& (FR_HIDEMATCHCASE
| FR_NOMATCHCASE
))
259 EnableWindow(GetDlgItem(hWnd
, chx2
), FALSE
);
260 if (*lpFlags
& FR_HIDEMATCHCASE
)
261 ShowWindow(GetDlgItem(hWnd
, chx2
), SW_HIDE
);
262 if (!(*lpFlags
& FR_SHOWHELP
)) {
263 EnableWindow(GetDlgItem(hWnd
, pshHelp
), FALSE
);
264 ShowWindow(GetDlgItem(hWnd
, pshHelp
), SW_HIDE
);
266 ShowWindow(hWnd
, SW_SHOWNORMAL
);
271 /***********************************************************************
272 * FINDDLG_WMCommand [internal]
274 static LRESULT
FINDDLG_WMCommand(HWND hWnd
, WPARAM wParam
,
275 HWND hwndOwner
, LPDWORD lpFlags
,
276 LPSTR lpstrFindWhat
, WORD wFindWhatLen
,
279 int uFindReplaceMessage
= RegisterWindowMessageA( FINDMSGSTRINGA
);
280 int uHelpMessage
= RegisterWindowMessageA( HELPMSGSTRINGA
);
285 GetDlgItemTextW(hWnd
, edt1
, (LPWSTR
)lpstrFindWhat
, wFindWhatLen
/2);
286 else GetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
, wFindWhatLen
);
287 if (IsDlgButtonChecked(hWnd
, rad2
))
289 else *lpFlags
&= ~FR_DOWN
;
290 if (IsDlgButtonChecked(hWnd
, chx1
))
291 *lpFlags
|= FR_WHOLEWORD
;
292 else *lpFlags
&= ~FR_WHOLEWORD
;
293 if (IsDlgButtonChecked(hWnd
, chx2
))
294 *lpFlags
|= FR_MATCHCASE
;
295 else *lpFlags
&= ~FR_MATCHCASE
;
296 *lpFlags
&= ~(FR_REPLACE
| FR_REPLACEALL
| FR_DIALOGTERM
);
297 *lpFlags
|= FR_FINDNEXT
;
298 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
299 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
302 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACE
| FR_REPLACEALL
);
303 *lpFlags
|= FR_DIALOGTERM
;
304 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
305 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
309 /* FIXME : should lpfr structure be passed as an argument ??? */
310 SendMessageA(hwndOwner
, uHelpMessage
, 0, 0);
317 /***********************************************************************
318 * FindTextDlgProc (COMMDLG.13)
320 BOOL16 CALLBACK
FindTextDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
323 HWND hWnd
= HWND_32(hWnd16
);
324 LPFINDREPLACE16 lpfr
;
328 return FINDDLG_WMInitDialog(hWnd
, lParam
, &(lpfr
->Flags
),
329 MapSL(lpfr
->lpstrFindWhat
), FALSE
);
331 lpfr
=MapSL(GetWindowLongPtrW(hWnd
, DWLP_USER
));
332 return FINDDLG_WMCommand(hWnd
, wParam
, HWND_32(lpfr
->hwndOwner
),
333 &lpfr
->Flags
, MapSL(lpfr
->lpstrFindWhat
),
334 lpfr
->wFindWhatLen
, FALSE
);
340 /***********************************************************************
341 * REPLACEDLG_WMInitDialog [internal]
343 static LRESULT
REPLACEDLG_WMInitDialog(HWND hWnd
, LPARAM lParam
,
344 LPDWORD lpFlags
, LPCSTR lpstrFindWhat
,
345 LPCSTR lpstrReplaceWith
, BOOL fUnicode
)
347 SetWindowLongPtrW(hWnd
, DWLP_USER
, lParam
);
348 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACE
| FR_REPLACEALL
| FR_DIALOGTERM
);
350 * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
351 * Replace / ReplaceAll buttons. Only after typing some text, the buttons should be
356 SetDlgItemTextW(hWnd
, edt1
, (LPCWSTR
)lpstrFindWhat
);
357 SetDlgItemTextW(hWnd
, edt2
, (LPCWSTR
)lpstrReplaceWith
);
360 SetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
);
361 SetDlgItemTextA(hWnd
, edt2
, lpstrReplaceWith
);
363 CheckDlgButton(hWnd
, chx1
, (*lpFlags
& FR_WHOLEWORD
) ? 1 : 0);
364 if (*lpFlags
& (FR_HIDEWHOLEWORD
| FR_NOWHOLEWORD
))
365 EnableWindow(GetDlgItem(hWnd
, chx1
), FALSE
);
366 if (*lpFlags
& FR_HIDEWHOLEWORD
)
367 ShowWindow(GetDlgItem(hWnd
, chx1
), SW_HIDE
);
368 CheckDlgButton(hWnd
, chx2
, (*lpFlags
& FR_MATCHCASE
) ? 1 : 0);
369 if (*lpFlags
& (FR_HIDEMATCHCASE
| FR_NOMATCHCASE
))
370 EnableWindow(GetDlgItem(hWnd
, chx2
), FALSE
);
371 if (*lpFlags
& FR_HIDEMATCHCASE
)
372 ShowWindow(GetDlgItem(hWnd
, chx2
), SW_HIDE
);
373 if (!(*lpFlags
& FR_SHOWHELP
)) {
374 EnableWindow(GetDlgItem(hWnd
, pshHelp
), FALSE
);
375 ShowWindow(GetDlgItem(hWnd
, pshHelp
), SW_HIDE
);
377 ShowWindow(hWnd
, SW_SHOWNORMAL
);
382 /***********************************************************************
383 * REPLACEDLG_WMCommand [internal]
385 static LRESULT
REPLACEDLG_WMCommand(HWND hWnd
, WPARAM16 wParam
,
386 HWND hwndOwner
, LPDWORD lpFlags
,
387 LPSTR lpstrFindWhat
, WORD wFindWhatLen
,
388 LPSTR lpstrReplaceWith
, WORD wReplaceWithLen
,
391 int uFindReplaceMessage
= RegisterWindowMessageA( FINDMSGSTRINGA
);
392 int uHelpMessage
= RegisterWindowMessageA( HELPMSGSTRINGA
);
398 GetDlgItemTextW(hWnd
, edt1
, (LPWSTR
)lpstrFindWhat
, wFindWhatLen
/2);
399 GetDlgItemTextW(hWnd
, edt2
, (LPWSTR
)lpstrReplaceWith
, wReplaceWithLen
/2);
402 GetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
, wFindWhatLen
);
403 GetDlgItemTextA(hWnd
, edt2
, lpstrReplaceWith
, wReplaceWithLen
);
405 if (IsDlgButtonChecked(hWnd
, chx1
))
406 *lpFlags
|= FR_WHOLEWORD
;
407 else *lpFlags
&= ~FR_WHOLEWORD
;
408 if (IsDlgButtonChecked(hWnd
, chx2
))
409 *lpFlags
|= FR_MATCHCASE
;
410 else *lpFlags
&= ~FR_MATCHCASE
;
411 *lpFlags
&= ~(FR_REPLACE
| FR_REPLACEALL
| FR_DIALOGTERM
);
412 *lpFlags
|= FR_FINDNEXT
;
413 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
414 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
417 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACE
| FR_REPLACEALL
);
418 *lpFlags
|= FR_DIALOGTERM
;
419 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
420 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
426 GetDlgItemTextW(hWnd
, edt1
, (LPWSTR
)lpstrFindWhat
, wFindWhatLen
/2);
427 GetDlgItemTextW(hWnd
, edt2
, (LPWSTR
)lpstrReplaceWith
, wReplaceWithLen
/2);
430 GetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
, wFindWhatLen
);
431 GetDlgItemTextA(hWnd
, edt2
, lpstrReplaceWith
, wReplaceWithLen
);
433 if (IsDlgButtonChecked(hWnd
, chx1
))
434 *lpFlags
|= FR_WHOLEWORD
;
435 else *lpFlags
&= ~FR_WHOLEWORD
;
436 if (IsDlgButtonChecked(hWnd
, chx2
))
437 *lpFlags
|= FR_MATCHCASE
;
438 else *lpFlags
&= ~FR_MATCHCASE
;
439 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACEALL
| FR_DIALOGTERM
);
440 *lpFlags
|= FR_REPLACE
;
441 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
442 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
447 GetDlgItemTextW(hWnd
, edt1
, (LPWSTR
)lpstrFindWhat
, wFindWhatLen
/2);
448 GetDlgItemTextW(hWnd
, edt2
, (LPWSTR
)lpstrReplaceWith
, wReplaceWithLen
/2);
451 GetDlgItemTextA(hWnd
, edt1
, lpstrFindWhat
, wFindWhatLen
);
452 GetDlgItemTextA(hWnd
, edt2
, lpstrReplaceWith
, wReplaceWithLen
);
454 if (IsDlgButtonChecked(hWnd
, chx1
))
455 *lpFlags
|= FR_WHOLEWORD
;
456 else *lpFlags
&= ~FR_WHOLEWORD
;
457 if (IsDlgButtonChecked(hWnd
, chx2
))
458 *lpFlags
|= FR_MATCHCASE
;
459 else *lpFlags
&= ~FR_MATCHCASE
;
460 *lpFlags
&= ~(FR_FINDNEXT
| FR_REPLACE
| FR_DIALOGTERM
);
461 *lpFlags
|= FR_REPLACEALL
;
462 SendMessageW( hwndOwner
, uFindReplaceMessage
, 0,
463 GetWindowLongPtrW(hWnd
, DWLP_USER
) );
466 /* FIXME : should lpfr structure be passed as an argument ??? */
467 SendMessageA(hwndOwner
, uHelpMessage
, 0, 0);
474 /***********************************************************************
475 * ReplaceTextDlgProc (COMMDLG.14)
477 BOOL16 CALLBACK
ReplaceTextDlgProc16(HWND16 hWnd16
, UINT16 wMsg
, WPARAM16 wParam
,
480 HWND hWnd
= HWND_32(hWnd16
);
481 LPFINDREPLACE16 lpfr
;
485 return REPLACEDLG_WMInitDialog(hWnd
, lParam
, &lpfr
->Flags
,
486 MapSL(lpfr
->lpstrFindWhat
),
487 MapSL(lpfr
->lpstrReplaceWith
), FALSE
);
489 lpfr
=MapSL(GetWindowLongPtrW(hWnd
, DWLP_USER
));
490 return REPLACEDLG_WMCommand(hWnd
, wParam
, HWND_32(lpfr
->hwndOwner
),
491 &lpfr
->Flags
, MapSL(lpfr
->lpstrFindWhat
),
492 lpfr
->wFindWhatLen
, MapSL(lpfr
->lpstrReplaceWith
),
493 lpfr
->wReplaceWithLen
, FALSE
);