Fixed callback parameters (bogus hWave); added acm conversion for
[wine.git] / dlls / commdlg / finddlg.c
blobc890d3ad46ffa92462468a6bb594165af17f268b
1 /*
2 * COMMDLG - 16 bits Find & Replace Text Dialogs
4 * Copyright 1994 Martin Ayotte
5 * Copyright 1996 Albrecht Kleine
6 */
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "wine/winuser16.h"
14 #include "commdlg.h"
15 #include "debugtools.h"
16 #include "cderr.h"
18 DEFAULT_DEBUG_CHANNEL(commdlg);
20 #include "cdlg.h"
22 struct FRPRIVATE
24 HANDLE16 hDlgTmpl16; /* handle for resource 16 */
25 HANDLE16 hResource16; /* handle for allocated resource 16 */
26 HANDLE16 hGlobal16; /* 16 bits mem block (resources) */
27 LPCVOID template; /* template for 32 bits resource */
28 BOOL find; /* TRUE if find dialog, FALSE if replace dialog */
29 FINDREPLACE16 *fr16;
32 #define LFRPRIVATE struct FRPRIVATE *
34 LRESULT WINAPI FindTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
35 LPARAM lParam);
36 LRESULT WINAPI ReplaceTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
37 LPARAM lParam);
39 /***********************************************************************
40 * FINDDLG_Get16BitsTemplate [internal]
42 * Get a template (FALSE if failure) when 16 bits dialogs are used
43 * by a 16 bits application
44 * FIXME : no test was done for the user-provided template cases
46 BOOL FINDDLG_Get16BitsTemplate(LFRPRIVATE lfr)
48 LPFINDREPLACE16 fr16 = lfr->fr16;
50 if (fr16->Flags & FR_ENABLETEMPLATEHANDLE)
52 lfr->template = GlobalLock16(fr16->hInstance);
53 if (!lfr->template)
55 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
56 return FALSE;
59 else if (fr16->Flags & FR_ENABLETEMPLATE)
61 HANDLE16 hResInfo;
62 if (!(hResInfo = FindResource16(fr16->hInstance,
63 MapSL(fr16->lpTemplateName),
64 RT_DIALOGA)))
66 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
67 return FALSE;
69 if (!(lfr->hDlgTmpl16 = LoadResource16( fr16->hInstance, hResInfo )))
71 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
72 return FALSE;
74 lfr->hResource16 = lfr->hDlgTmpl16;
75 lfr->template = LockResource16(lfr->hResource16);
76 if (!lfr->template)
78 FreeResource16(lfr->hResource16);
79 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
80 return FALSE;
83 else
84 { /* get resource from (32 bits) own Wine resource; convert it to 16 */
85 HANDLE hResInfo, hDlgTmpl32;
86 LPCVOID template32;
87 DWORD size;
88 HGLOBAL16 hGlobal16;
90 if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
91 lfr->find ?
92 MAKEINTRESOURCEA(FINDDLGORD):MAKEINTRESOURCEA(REPLACEDLGORD),
93 RT_DIALOGA)))
95 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
96 return FALSE;
98 if (!(hDlgTmpl32 = LoadResource(COMMDLG_hInstance32, hResInfo )) ||
99 !(template32 = LockResource( hDlgTmpl32 )))
101 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
102 return FALSE;
104 size = SizeofResource(GetModuleHandleA("COMDLG32"), hResInfo);
105 hGlobal16 = GlobalAlloc16(0, size);
106 if (!hGlobal16)
108 COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE);
109 ERR("alloc failure for %ld bytes\n", size);
110 return FALSE;
112 lfr->template = GlobalLock16(hGlobal16);
113 if (!lfr->template)
115 COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE);
116 ERR("global lock failure for %x handle\n", hGlobal16);
117 GlobalFree16(hGlobal16);
118 return FALSE;
120 ConvertDialog32To16((LPVOID)template32, size, (LPVOID)lfr->template);
121 lfr->hDlgTmpl16 = hGlobal16;
122 lfr->hGlobal16 = hGlobal16;
124 return TRUE;
128 /***********************************************************************
129 * FINDDLG_FreeResources [internal]
131 * Free resources allocated
133 void FINDDLG_FreeResources(LFRPRIVATE lfr)
135 /* free resources */
136 if (lfr->fr16->Flags & FR_ENABLETEMPLATEHANDLE)
137 GlobalUnlock16(lfr->fr16->hInstance);
138 if (lfr->hResource16)
140 GlobalUnlock16(lfr->hResource16);
141 FreeResource16(lfr->hResource16);
143 if (lfr->hGlobal16)
145 GlobalUnlock16(lfr->hGlobal16);
146 GlobalFree16(lfr->hGlobal16);
150 /***********************************************************************
151 * FindText16 (COMMDLG.11)
153 HWND16 WINAPI FindText16( SEGPTR find )
155 HANDLE16 hInst;
156 HWND16 ret = 0;
157 FARPROC16 ptr;
158 LFRPRIVATE lfr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FRPRIVATE));
160 if (!lfr) return 0;
161 lfr->fr16 = MapSL(find);
162 lfr->find = TRUE;
163 if (FINDDLG_Get16BitsTemplate(lfr))
165 hInst = GetWindowLongA( lfr->fr16->hwndOwner , GWL_HINSTANCE);
166 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 13);
167 ret = CreateDialogIndirectParam16( hInst, lfr->template,
168 lfr->fr16->hwndOwner, (DLGPROC16) ptr, find);
169 FINDDLG_FreeResources(lfr);
171 HeapFree(GetProcessHeap(), 0, lfr);
172 return ret;
176 /***********************************************************************
177 * ReplaceText16 (COMMDLG.12)
179 HWND16 WINAPI ReplaceText16( SEGPTR find )
181 HANDLE16 hInst;
182 HWND16 ret = 0;
183 FARPROC16 ptr;
184 LFRPRIVATE lfr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct FRPRIVATE));
186 if (!lfr) return 0;
188 * FIXME : We should do error checking on the lpFind structure here
189 * and make CommDlgExtendedError() return the error condition.
191 lfr->fr16 = MapSL(find);
192 lfr->find = FALSE;
193 if (FINDDLG_Get16BitsTemplate(lfr))
195 hInst = GetWindowLongA( lfr->fr16->hwndOwner , GWL_HINSTANCE);
196 ptr = GetProcAddress16(GetModuleHandle16("COMMDLG"), (LPCSTR) 14);
197 ret = CreateDialogIndirectParam16( hInst, lfr->template,
198 lfr->fr16->hwndOwner, (DLGPROC16) ptr, find);
200 FINDDLG_FreeResources(lfr);
202 HeapFree(GetProcessHeap(), 0, lfr);
203 return ret;
207 /***********************************************************************
208 * FINDDLG_WMInitDialog [internal]
210 static LRESULT FINDDLG_WMInitDialog(HWND hWnd, LPARAM lParam, LPDWORD lpFlags,
211 LPSTR lpstrFindWhat, BOOL fUnicode)
213 SetWindowLongA(hWnd, DWL_USER, lParam);
214 *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
216 * FIXME : If the initial FindWhat string is empty, we should disable the
217 * FindNext (IDOK) button. Only after typing some text, the button should be
218 * enabled.
220 if (fUnicode) SetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat);
221 else SetDlgItemTextA(hWnd, edt1, lpstrFindWhat);
222 CheckRadioButton(hWnd, rad1, rad2, (*lpFlags & FR_DOWN) ? rad2 : rad1);
223 if (*lpFlags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
224 EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
225 EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
227 if (*lpFlags & FR_HIDEUPDOWN) {
228 ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
229 ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
230 ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
232 CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
233 if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
234 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
235 if (*lpFlags & FR_HIDEWHOLEWORD)
236 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
237 CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
238 if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
239 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
240 if (*lpFlags & FR_HIDEMATCHCASE)
241 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
242 if (!(*lpFlags & FR_SHOWHELP)) {
243 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
244 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
246 ShowWindow(hWnd, SW_SHOWNORMAL);
247 return TRUE;
251 /***********************************************************************
252 * FINDDLG_WMCommand [internal]
254 static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam,
255 HWND hwndOwner, LPDWORD lpFlags,
256 LPSTR lpstrFindWhat, WORD wFindWhatLen,
257 BOOL fUnicode)
259 int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA );
260 int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA );
262 switch (wParam) {
263 case IDOK:
264 if (fUnicode)
265 GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
266 else GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
267 if (IsDlgButtonChecked(hWnd, rad2))
268 *lpFlags |= FR_DOWN;
269 else *lpFlags &= ~FR_DOWN;
270 if (IsDlgButtonChecked(hWnd, chx1))
271 *lpFlags |= FR_WHOLEWORD;
272 else *lpFlags &= ~FR_WHOLEWORD;
273 if (IsDlgButtonChecked(hWnd, chx2))
274 *lpFlags |= FR_MATCHCASE;
275 else *lpFlags &= ~FR_MATCHCASE;
276 *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
277 *lpFlags |= FR_FINDNEXT;
278 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
279 GetWindowLongA(hWnd, DWL_USER) );
280 return TRUE;
281 case IDCANCEL:
282 *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
283 *lpFlags |= FR_DIALOGTERM;
284 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
285 GetWindowLongA(hWnd, DWL_USER) );
286 DestroyWindow(hWnd);
287 return TRUE;
288 case pshHelp:
289 /* FIXME : should lpfr structure be passed as an argument ??? */
290 SendMessageA(hwndOwner, uHelpMessage, 0, 0);
291 return TRUE;
293 return FALSE;
297 /***********************************************************************
298 * FindTextDlgProc16 (COMMDLG.13)
300 LRESULT WINAPI FindTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
301 LPARAM lParam)
303 LPFINDREPLACE16 lpfr;
304 switch (wMsg) {
305 case WM_INITDIALOG:
306 lpfr=MapSL(lParam);
307 return FINDDLG_WMInitDialog(hWnd, lParam, &(lpfr->Flags),
308 MapSL(lpfr->lpstrFindWhat), FALSE);
309 case WM_COMMAND:
310 lpfr=MapSL(GetWindowLongA(hWnd, DWL_USER));
311 return FINDDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner,
312 &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),
313 lpfr->wFindWhatLen, FALSE);
315 return FALSE;
319 /***********************************************************************
320 * REPLACEDLG_WMInitDialog [internal]
322 static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, LPARAM lParam,
323 LPDWORD lpFlags, LPSTR lpstrFindWhat,
324 LPSTR lpstrReplaceWith, BOOL fUnicode)
326 SetWindowLongA(hWnd, DWL_USER, lParam);
327 *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
329 * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
330 * Replace / ReplaceAll buttons. Only after typing some text, the buttons should be
331 * enabled.
333 if (fUnicode)
335 SetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat);
336 SetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith);
337 } else
339 SetDlgItemTextA(hWnd, edt1, lpstrFindWhat);
340 SetDlgItemTextA(hWnd, edt2, lpstrReplaceWith);
342 CheckDlgButton(hWnd, chx1, (*lpFlags & FR_WHOLEWORD) ? 1 : 0);
343 if (*lpFlags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
344 EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
345 if (*lpFlags & FR_HIDEWHOLEWORD)
346 ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
347 CheckDlgButton(hWnd, chx2, (*lpFlags & FR_MATCHCASE) ? 1 : 0);
348 if (*lpFlags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
349 EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
350 if (*lpFlags & FR_HIDEMATCHCASE)
351 ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
352 if (!(*lpFlags & FR_SHOWHELP)) {
353 EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
354 ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
356 ShowWindow(hWnd, SW_SHOWNORMAL);
357 return TRUE;
361 /***********************************************************************
362 * REPLACEDLG_WMCommand [internal]
364 static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM16 wParam,
365 HWND hwndOwner, LPDWORD lpFlags,
366 LPSTR lpstrFindWhat, WORD wFindWhatLen,
367 LPSTR lpstrReplaceWith, WORD wReplaceWithLen,
368 BOOL fUnicode)
370 int uFindReplaceMessage = RegisterWindowMessageA( FINDMSGSTRINGA );
371 int uHelpMessage = RegisterWindowMessageA( HELPMSGSTRINGA );
373 switch (wParam) {
374 case IDOK:
375 if (fUnicode)
377 GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
378 GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
379 } else
381 GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
382 GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
384 if (IsDlgButtonChecked(hWnd, chx1))
385 *lpFlags |= FR_WHOLEWORD;
386 else *lpFlags &= ~FR_WHOLEWORD;
387 if (IsDlgButtonChecked(hWnd, chx2))
388 *lpFlags |= FR_MATCHCASE;
389 else *lpFlags &= ~FR_MATCHCASE;
390 *lpFlags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
391 *lpFlags |= FR_FINDNEXT;
392 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
393 GetWindowLongA(hWnd, DWL_USER) );
394 return TRUE;
395 case IDCANCEL:
396 *lpFlags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
397 *lpFlags |= FR_DIALOGTERM;
398 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
399 GetWindowLongA(hWnd, DWL_USER) );
400 DestroyWindow(hWnd);
401 return TRUE;
402 case psh1:
403 if (fUnicode)
405 GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
406 GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
407 } else
409 GetDlgItemTextA(hWnd, edt1, lpstrFindWhat, wFindWhatLen);
410 GetDlgItemTextA(hWnd, edt2, lpstrReplaceWith, wReplaceWithLen);
412 if (IsDlgButtonChecked(hWnd, chx1))
413 *lpFlags |= FR_WHOLEWORD;
414 else *lpFlags &= ~FR_WHOLEWORD;
415 if (IsDlgButtonChecked(hWnd, chx2))
416 *lpFlags |= FR_MATCHCASE;
417 else *lpFlags &= ~FR_MATCHCASE;
418 *lpFlags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
419 *lpFlags |= FR_REPLACE;
420 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
421 GetWindowLongA(hWnd, DWL_USER) );
422 return TRUE;
423 case psh2:
424 if (fUnicode)
426 GetDlgItemTextW(hWnd, edt1, (LPWSTR)lpstrFindWhat, wFindWhatLen/2);
427 GetDlgItemTextW(hWnd, edt2, (LPWSTR)lpstrReplaceWith, wReplaceWithLen/2);
428 } else
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_REPLACE | FR_DIALOGTERM);
440 *lpFlags |= FR_REPLACEALL;
441 SendMessageA(hwndOwner, uFindReplaceMessage, 0,
442 GetWindowLongA(hWnd, DWL_USER) );
443 return TRUE;
444 case pshHelp:
445 /* FIXME : should lpfr structure be passed as an argument ??? */
446 SendMessageA(hwndOwner, uHelpMessage, 0, 0);
447 return TRUE;
449 return FALSE;
453 /***********************************************************************
454 * ReplaceTextDlgProc16 (COMMDLG.14)
456 LRESULT WINAPI ReplaceTextDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
457 LPARAM lParam)
459 LPFINDREPLACE16 lpfr;
460 switch (wMsg) {
461 case WM_INITDIALOG:
462 lpfr=MapSL(lParam);
463 return REPLACEDLG_WMInitDialog(hWnd, lParam, &lpfr->Flags,
464 MapSL(lpfr->lpstrFindWhat),
465 MapSL(lpfr->lpstrReplaceWith), FALSE);
466 case WM_COMMAND:
467 lpfr=MapSL(GetWindowLongA(hWnd, DWL_USER));
468 return REPLACEDLG_WMCommand(hWnd, wParam, lpfr->hwndOwner,
469 &lpfr->Flags, MapSL(lpfr->lpstrFindWhat),
470 lpfr->wFindWhatLen, MapSL(lpfr->lpstrReplaceWith),
471 lpfr->wReplaceWithLen, FALSE);
473 return FALSE;