1 /* 2 * Common Dialog Boxes interface (32 bit) 3 * Find/Replace 4 * 5 * Copyright 1998,1999 Bertho A. Stultiens 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 <stdarg.h> 23 #include <string.h> 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winnls.h" 27 #include "wingdi.h" 28 #include "winuser.h" 29 #include "commdlg.h" 30 #include "cderr.h" 31 #include "dlgs.h" 32 #include "wine/debug.h" 33 #include "wine/heap.h" 34 35 WINE_DEFAULT_DEBUG_CHANNEL(commdlg); 36 37 #include "cdlg.h" 38 39 40 /*-----------------------------------------------------------------------*/ 41 42 static UINT FindReplaceMessage; 43 static UINT HelpMessage; 44 45 #define FR_MASK (FR_DOWN | FR_MATCHCASE | FR_WHOLEWORD | FR_REPLACEALL | FR_REPLACE | FR_FINDNEXT | FR_DIALOGTERM) 46 /* CRITICAL_SECTION COMDLG32_CritSect; */ 47 48 /* Notes: 49 * MS uses a critical section at a few locations. However, I fail to 50 * see the reason for this. Their comdlg32.dll has a few race conditions 51 * but _not_ at those places that are protected with the mutex (there are 52 * globals that seem to hold info for the wndproc). 53 * 54 * FindText[AW]/ReplaceText[AW] 55 * The find/replace calls are passed a structure that is _not_ used 56 * internally. There is a local copy that holds the running info to 57 * be able to combine xxxA and xxxW calls. The passed pointer is 58 * returned upon sendmessage. Apps won't break this way when they rely 59 * on the original pointer. This will work as long as the sizes of 60 * FINDREPLACEA == FINDREPLACEW. The local copy will also prevent 61 * the app to see the wine-specific extra flags to distinguish between 62 * A/W and Find/Replace. 63 */ 64 65 66 /*********************************************************************** 67 * COMDLG32_FR_GetFlags [internal] 68 * Returns the button state that needs to be reported to the caller. 69 * RETURNS 70 * Current state of check and radio buttons 71 */ 72 static DWORD COMDLG32_FR_GetFlags(HWND hDlgWnd) 73 { 74 DWORD flags = 0; 75 if(IsDlgButtonChecked(hDlgWnd, rad2) == BST_CHECKED) 76 flags |= FR_DOWN; 77 if(IsDlgButtonChecked(hDlgWnd, chx1) == BST_CHECKED) 78 flags |= FR_WHOLEWORD; 79 if(IsDlgButtonChecked(hDlgWnd, chx2) == BST_CHECKED) 80 flags |= FR_MATCHCASE; 81 return flags; 82 } 83 84 /*********************************************************************** 85 * COMDLG32_FR_HandleWMCommand [internal] 86 * Handle WM_COMMAND messages... 87 */ 88 static void COMDLG32_FR_HandleWMCommand(HWND hDlgWnd, COMDLG32_FR_Data *pData, int Id, int NotifyCode) 89 { 90 DWORD flag; 91 92 #ifndef __REACTOS__ 93 pData->user_fr.fra->Flags &= ~FR_MASK; /* Clear return flags */ 94 if(pData->fr.Flags & FR_WINE_REPLACE) /* Replace always goes down... */ 95 pData->user_fr.fra->Flags |= FR_DOWN; 96 #endif 97 98 if(NotifyCode == BN_CLICKED) 99 { 100 switch(Id) 101 { 102 case IDOK: /* Find Next */ 103 if(GetDlgItemTextA(hDlgWnd, edt1, pData->fr.lpstrFindWhat, pData->fr.wFindWhatLen) > 0) 104 { 105 #ifdef __REACTOS__ 106 pData->user_fr.fra->Flags &= ~FR_MASK; /* Clear return flags */ 107 if(pData->fr.Flags & FR_WINE_REPLACE) /* Replace always goes down... */ 108 pData->user_fr.fra->Flags |= FR_DOWN; 109 #endif 110 pData->user_fr.fra->Flags |= COMDLG32_FR_GetFlags(hDlgWnd) | FR_FINDNEXT; 111 if(pData->fr.Flags & FR_WINE_UNICODE) 112 { 113 MultiByteToWideChar( CP_ACP, 0, pData->fr.lpstrFindWhat, -1, 114 pData->user_fr.frw->lpstrFindWhat, 115 0x7fffffff ); 116 } 117 else 118 { 119 strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); 120 } 121 SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); 122 } 123 break; 124 125 case IDCANCEL: 126 #ifdef __REACTOS__ 127 pData->user_fr.fra->Flags &= ~FR_MASK; /* Clear return flags */ 128 if(pData->fr.Flags & FR_WINE_REPLACE) /* Replace always goes down... */ 129 pData->user_fr.fra->Flags |= FR_DOWN; 130 #endif 131 pData->user_fr.fra->Flags |= COMDLG32_FR_GetFlags(hDlgWnd) | FR_DIALOGTERM; 132 SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); 133 DestroyWindow(hDlgWnd); 134 break; 135 136 case psh2: /* Replace All */ 137 flag = FR_REPLACEALL; 138 goto Replace; 139 140 case psh1: /* Replace */ 141 flag = FR_REPLACE; 142 Replace: 143 if((pData->fr.Flags & FR_WINE_REPLACE) 144 && GetDlgItemTextA(hDlgWnd, edt1, pData->fr.lpstrFindWhat, pData->fr.wFindWhatLen) > 0) 145 { 146 pData->fr.lpstrReplaceWith[0] = 0; /* In case the next GetDlgItemText Fails */ 147 GetDlgItemTextA(hDlgWnd, edt2, pData->fr.lpstrReplaceWith, pData->fr.wReplaceWithLen); 148 #ifdef __REACTOS__ 149 pData->user_fr.fra->Flags &= ~FR_MASK; /* Clear return flags */ 150 if(pData->fr.Flags & FR_WINE_REPLACE) /* Replace always goes down... */ 151 pData->user_fr.fra->Flags |= FR_DOWN; 152 #endif 153 pData->user_fr.fra->Flags |= COMDLG32_FR_GetFlags(hDlgWnd) | flag; 154 if(pData->fr.Flags & FR_WINE_UNICODE) 155 { 156 MultiByteToWideChar( CP_ACP, 0, pData->fr.lpstrFindWhat, -1, 157 pData->user_fr.frw->lpstrFindWhat, 158 0x7fffffff ); 159 MultiByteToWideChar( CP_ACP, 0, pData->fr.lpstrReplaceWith, -1, 160 pData->user_fr.frw->lpstrReplaceWith, 161 0x7fffffff ); 162 } 163 else 164 { 165 strcpy(pData->user_fr.fra->lpstrFindWhat, pData->fr.lpstrFindWhat); 166 strcpy(pData->user_fr.fra->lpstrReplaceWith, pData->fr.lpstrReplaceWith); 167 } 168 SendMessageA(pData->fr.hwndOwner, FindReplaceMessage, 0, (LPARAM)pData->user_fr.fra); 169 } 170 break; 171 172 case pshHelp: 173 #ifdef __REACTOS__ 174 pData->user_fr.fra->Flags &= ~FR_MASK; /* Clear return flags */ 175 if(pData->fr.Flags & FR_WINE_REPLACE) /* Replace always goes down... */ 176 pData->user_fr.fra->Flags |= FR_DOWN; 177 #endif 178 pData->user_fr.fra->Flags |= COMDLG32_FR_GetFlags(hDlgWnd); 179 SendMessageA(pData->fr.hwndOwner, HelpMessage, (WPARAM)hDlgWnd, (LPARAM)pData->user_fr.fra); 180 break; 181 } 182 } 183 else if(NotifyCode == EN_CHANGE && Id == edt1) 184 { 185 BOOL enable = SendDlgItemMessageA(hDlgWnd, edt1, WM_GETTEXTLENGTH, 0, 0) > 0; 186 EnableWindow(GetDlgItem(hDlgWnd, IDOK), enable); 187 if(pData->fr.Flags & FR_WINE_REPLACE) 188 { 189 EnableWindow(GetDlgItem(hDlgWnd, psh1), enable); 190 EnableWindow(GetDlgItem(hDlgWnd, psh2), enable); 191 } 192 } 193 } 194 195 /*********************************************************************** 196 * COMDLG32_FindReplaceDlgProc [internal] 197 * [Find/Replace]Text32[A/W] window procedure. 198 */ 199 static INT_PTR CALLBACK COMDLG32_FindReplaceDlgProc(HWND hDlgWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 200 { 201 COMDLG32_FR_Data *pdata = GetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom); 202 INT_PTR retval = TRUE; 203 204 if(iMsg == WM_INITDIALOG) 205 { 206 pdata = (COMDLG32_FR_Data *)lParam; 207 if(!SetPropA(hDlgWnd, (LPSTR)COMDLG32_Atom, (HANDLE)pdata)) 208 { 209 ERR("Could not Set prop; invent a graceful exit?...\n"); 210 DestroyWindow(hDlgWnd); 211 return FALSE; 212 } 213 SendDlgItemMessageA(hDlgWnd, edt1, EM_SETLIMITTEXT, pdata->fr.wFindWhatLen, 0); 214 SendDlgItemMessageA(hDlgWnd, edt1, WM_SETTEXT, 0, (LPARAM)pdata->fr.lpstrFindWhat); 215 if(pdata->fr.Flags & FR_WINE_REPLACE) 216 { 217 SendDlgItemMessageA(hDlgWnd, edt2, EM_SETLIMITTEXT, pdata->fr.wReplaceWithLen, 0); 218 SendDlgItemMessageA(hDlgWnd, edt2, WM_SETTEXT, 0, (LPARAM)pdata->fr.lpstrReplaceWith); 219 } 220 221 if(!(pdata->fr.Flags & FR_SHOWHELP)) 222 ShowWindow(GetDlgItem(hDlgWnd, pshHelp), SW_HIDE); 223 if(pdata->fr.Flags & FR_HIDEUPDOWN) 224 { 225 ShowWindow(GetDlgItem(hDlgWnd, rad1), SW_HIDE); 226 ShowWindow(GetDlgItem(hDlgWnd, rad2), SW_HIDE); 227 ShowWindow(GetDlgItem(hDlgWnd, grp1), SW_HIDE); 228 } 229 else if(pdata->fr.Flags & FR_NOUPDOWN) 230 { 231 EnableWindow(GetDlgItem(hDlgWnd, rad1), FALSE); 232 EnableWindow(GetDlgItem(hDlgWnd, rad2), FALSE); 233 EnableWindow(GetDlgItem(hDlgWnd, grp1), FALSE); 234 } 235 else 236 { 237 SendDlgItemMessageA(hDlgWnd, rad1, BM_SETCHECK, pdata->fr.Flags & FR_DOWN ? 0 : BST_CHECKED, 0); 238 SendDlgItemMessageA(hDlgWnd, rad2, BM_SETCHECK, pdata->fr.Flags & FR_DOWN ? BST_CHECKED : 0, 0); 239 } 240 241 if(pdata->fr.Flags & FR_HIDEMATCHCASE) 242 ShowWindow(GetDlgItem(hDlgWnd, chx2), SW_HIDE); 243 else if(pdata->fr.Flags & FR_NOMATCHCASE) 244 EnableWindow(GetDlgItem(hDlgWnd, chx2), FALSE); 245 else 246 SendDlgItemMessageA(hDlgWnd, chx2, BM_SETCHECK, pdata->fr.Flags & FR_MATCHCASE ? BST_CHECKED : 0, 0); 247 248 if(pdata->fr.Flags & FR_HIDEWHOLEWORD) 249 ShowWindow(GetDlgItem(hDlgWnd, chx1), SW_HIDE); 250 else if(pdata->fr.Flags & FR_NOWHOLEWORD) 251 EnableWindow(GetDlgItem(hDlgWnd, chx1), FALSE); 252 else 253 SendDlgItemMessageA(hDlgWnd, chx1, BM_SETCHECK, pdata->fr.Flags & FR_WHOLEWORD ? BST_CHECKED : 0, 0); 254 255 /* We did the init here, now call the hook if requested */ 256 257 /* We do not do ShowWindow if hook exists and is FALSE */ 258 /* per MSDN Article Q96135 */ 259 if((pdata->fr.Flags & FR_ENABLEHOOK) 260 && ! pdata->fr.lpfnHook(hDlgWnd, iMsg, wParam, (LPARAM) &pdata->fr)) 261 return TRUE; 262 ShowWindow(hDlgWnd, SW_SHOWNORMAL); 263 UpdateWindow(hDlgWnd); 264 return TRUE; 265 } 266 267 if(pdata && (pdata->fr.Flags & FR_ENABLEHOOK)) 268 { 269 retval = pdata->fr.lpfnHook(hDlgWnd, iMsg, wParam, lParam); 270 } 271 else 272 retval = FALSE; 273 274 if(pdata && !retval) 275 { 276 retval = TRUE; 277 switch(iMsg) 278 { 279 case WM_COMMAND: 280 COMDLG32_FR_HandleWMCommand(hDlgWnd, pdata, LOWORD(wParam), HIWORD(wParam)); 281 break; 282 283 case WM_CLOSE: 284 COMDLG32_FR_HandleWMCommand(hDlgWnd, pdata, IDCANCEL, BN_CLICKED); 285 break; 286 287 case WM_HELP: 288 /* Heeeeelp! */ 289 FIXME("Got WM_HELP. Who is gonna supply it?\n"); 290 break; 291 292 case WM_CONTEXTMENU: 293 /* Heeeeelp! */ 294 FIXME("Got WM_CONTEXTMENU. Who is gonna supply it?\n"); 295 break; 296 /* FIXME: Handle F1 help */ 297 298 default: 299 retval = FALSE; /* We did not handle the message */ 300 } 301 } 302 303 /* WM_DESTROY is a special case. 304 * We need to ensure that the allocated memory is freed just before 305 * the dialog is killed. We also need to remove the added prop. 306 */ 307 if(iMsg == WM_DESTROY) 308 { 309 RemovePropA(hDlgWnd, (LPSTR)COMDLG32_Atom); 310 heap_free(pdata); 311 } 312 313 return retval; 314 } 315 316 /*********************************************************************** 317 * COMDLG32_FR_CheckPartial [internal] 318 * Check various fault conditions in the supplied parameters that 319 * cause an extended error to be reported. 320 * RETURNS 321 * TRUE: Success 322 * FALSE: Failure 323 */ 324 static BOOL COMDLG32_FR_CheckPartial( 325 const FINDREPLACEA *pfr, /* [in] Find structure */ 326 BOOL Replace /* [in] True if called as replace */ 327 ) { 328 if(!pfr) 329 { 330 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); 331 return FALSE; 332 } 333 334 if(pfr->lStructSize != sizeof(FINDREPLACEA)) 335 { 336 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); 337 return FALSE; 338 } 339 340 if(!IsWindow(pfr->hwndOwner)) 341 { 342 COMDLG32_SetCommDlgExtendedError(CDERR_DIALOGFAILURE); 343 return FALSE; 344 } 345 346 if((pfr->wFindWhatLen < 1 || !pfr->lpstrFindWhat) 347 ||(Replace && !pfr->lpstrReplaceWith)) 348 { 349 COMDLG32_SetCommDlgExtendedError(FRERR_BUFFERLENGTHZERO); 350 return FALSE; 351 } 352 353 if((FindReplaceMessage = RegisterWindowMessageA(FINDMSGSTRINGA)) == 0) 354 { 355 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); 356 return FALSE; 357 } 358 if((HelpMessage = RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) 359 { 360 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); 361 return FALSE; 362 } 363 364 if((pfr->Flags & FR_ENABLEHOOK) && !pfr->lpfnHook) 365 { 366 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); 367 return FALSE; 368 } 369 370 if((pfr->Flags & FR_ENABLETEMPLATEHANDLE) && !pfr->hInstance) 371 { 372 COMDLG32_SetCommDlgExtendedError(CDERR_NOHINSTANCE); 373 return FALSE; 374 } 375 376 return TRUE; 377 } 378 379 /*********************************************************************** 380 * COMDLG32_FR_DoFindReplace [internal] 381 * Actual load and creation of the Find/Replace dialog. 382 * RETURNS 383 * Window handle to created dialog:Success 384 * NULL:Failure 385 */ 386 static HWND COMDLG32_FR_DoFindReplace( 387 COMDLG32_FR_Data *pdata /* [in] Internal data structure */ 388 ) { 389 HWND hdlgwnd = 0; 390 HGLOBAL loadrc; 391 DWORD error; 392 LPDLGTEMPLATEW rcs; 393 394 TRACE("hInst=%p, Flags=%08x\n", pdata->fr.hInstance, pdata->fr.Flags); 395 396 if(!(pdata->fr.Flags & FR_ENABLETEMPLATEHANDLE)) 397 { 398 HMODULE hmod = COMDLG32_hInstance; 399 HRSRC htemplate; 400 if(pdata->fr.Flags & FR_ENABLETEMPLATE) 401 { 402 hmod = pdata->fr.hInstance; 403 if(pdata->fr.Flags & FR_WINE_UNICODE) 404 { 405 htemplate = FindResourceW(hmod, (LPCWSTR)pdata->fr.lpTemplateName, (LPWSTR)RT_DIALOG); 406 } 407 else 408 { 409 htemplate = FindResourceA(hmod, pdata->fr.lpTemplateName, (LPCSTR)RT_DIALOG); 410 } 411 } 412 else 413 { 414 int rcid = pdata->fr.Flags & FR_WINE_REPLACE ? REPLACEDLGORD 415 : FINDDLGORD; 416 htemplate = FindResourceA(hmod, MAKEINTRESOURCEA(rcid), (LPCSTR)RT_DIALOG); 417 } 418 if(!htemplate) 419 { 420 error = CDERR_FINDRESFAILURE; 421 goto cleanup; 422 } 423 424 loadrc = LoadResource(hmod, htemplate); 425 } 426 else 427 { 428 loadrc = pdata->fr.hInstance; 429 } 430 431 if(!loadrc) 432 { 433 error = CDERR_LOADRESFAILURE; 434 goto cleanup; 435 } 436 437 if((rcs = LockResource(loadrc)) == NULL) 438 { 439 error = CDERR_LOCKRESFAILURE; 440 goto cleanup; 441 } 442 443 hdlgwnd = CreateDialogIndirectParamA(COMDLG32_hInstance, 444 rcs, 445 pdata->fr.hwndOwner, 446 COMDLG32_FindReplaceDlgProc, 447 (LPARAM)pdata); 448 if(!hdlgwnd) 449 { 450 error = CDERR_DIALOGFAILURE; 451 cleanup: 452 COMDLG32_SetCommDlgExtendedError(error); 453 heap_free(pdata); 454 } 455 return hdlgwnd; 456 } 457 458 /*********************************************************************** 459 * FindTextA [COMDLG32.@] 460 * 461 * See FindTextW. 462 */ 463 HWND WINAPI FindTextA( 464 LPFINDREPLACEA pfr /* [in] Find/replace structure*/ 465 ) { 466 COMDLG32_FR_Data *pdata; 467 468 TRACE("LPFINDREPLACE=%p\n", pfr); 469 470 if(!COMDLG32_FR_CheckPartial(pfr, FALSE)) 471 return 0; 472 473 if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL) 474 return 0; /* Error has been set */ 475 476 pdata->user_fr.fra = pfr; 477 pdata->fr = *pfr; 478 return COMDLG32_FR_DoFindReplace(pdata); 479 } 480 481 /*********************************************************************** 482 * ReplaceTextA [COMDLG32.@] 483 * 484 * See ReplaceTextW. 485 */ 486 HWND WINAPI ReplaceTextA( 487 LPFINDREPLACEA pfr /* [in] Find/replace structure*/ 488 ) { 489 COMDLG32_FR_Data *pdata; 490 491 TRACE("LPFINDREPLACE=%p\n", pfr); 492 493 if(!COMDLG32_FR_CheckPartial(pfr, TRUE)) 494 return 0; 495 496 if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data))) == NULL) 497 return 0; /* Error has been set */ 498 499 pdata->user_fr.fra = pfr; 500 pdata->fr = *pfr; 501 pdata->fr.Flags |= FR_WINE_REPLACE; 502 return COMDLG32_FR_DoFindReplace(pdata); 503 } 504 505 /*********************************************************************** 506 * FindTextW [COMDLG32.@] 507 * 508 * Create a modeless find-text dialog box. 509 * 510 * RETURNS 511 * Window handle to created dialog: Success 512 * NULL: Failure 513 */ 514 HWND WINAPI FindTextW( 515 LPFINDREPLACEW pfr /* [in] Find/replace structure*/ 516 ) { 517 COMDLG32_FR_Data *pdata; 518 DWORD len; 519 520 TRACE("LPFINDREPLACE=%p\n", pfr); 521 522 if(!COMDLG32_FR_CheckPartial((LPFINDREPLACEA)pfr, FALSE)) 523 return 0; 524 525 len = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, 526 NULL, 0, NULL, NULL ); 527 if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data) + len)) == NULL) 528 return 0; /* Error has been set */ 529 530 pdata->user_fr.frw = pfr; 531 pdata->fr = *(LPFINDREPLACEA)pfr; /* FINDREPLACEx have same size */ 532 pdata->fr.Flags |= FR_WINE_UNICODE; 533 pdata->fr.lpstrFindWhat = (LPSTR)(pdata + 1); /* Set string pointer */ 534 WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, 535 pdata->fr.lpstrFindWhat, len, NULL, NULL ); 536 return COMDLG32_FR_DoFindReplace(pdata); 537 } 538 539 /*********************************************************************** 540 * ReplaceTextW [COMDLG32.@] 541 * 542 * Create a modeless replace-text dialog box. 543 * 544 * RETURNS 545 * Window handle to created dialog: Success 546 * NULL: Failure 547 */ 548 HWND WINAPI ReplaceTextW( 549 LPFINDREPLACEW pfr /* [in] Find/replace structure*/ 550 ) { 551 COMDLG32_FR_Data *pdata; 552 DWORD len1, len2; 553 554 TRACE("LPFINDREPLACE=%p\n", pfr); 555 556 if(!COMDLG32_FR_CheckPartial((LPFINDREPLACEA)pfr, TRUE)) 557 return 0; 558 559 len1 = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, 560 NULL, 0, NULL, NULL ); 561 len2 = WideCharToMultiByte( CP_ACP, 0, pfr->lpstrReplaceWith, pfr->wReplaceWithLen, 562 NULL, 0, NULL, NULL ); 563 if((pdata = COMDLG32_AllocMem(sizeof(COMDLG32_FR_Data) + len1 + len2)) == NULL) 564 return 0; /* Error has been set */ 565 566 pdata->user_fr.frw = pfr; 567 pdata->fr = *(LPFINDREPLACEA)pfr; /* FINDREPLACEx have same size */ 568 pdata->fr.Flags |= FR_WINE_REPLACE | FR_WINE_UNICODE; 569 pdata->fr.lpstrFindWhat = (LPSTR)(pdata + 1); /* Set string pointer */ 570 pdata->fr.lpstrReplaceWith = pdata->fr.lpstrFindWhat + len1; 571 572 WideCharToMultiByte( CP_ACP, 0, pfr->lpstrFindWhat, pfr->wFindWhatLen, 573 pdata->fr.lpstrFindWhat, len1, NULL, NULL ); 574 WideCharToMultiByte( CP_ACP, 0, pfr->lpstrReplaceWith, pfr->wReplaceWithLen, 575 pdata->fr.lpstrReplaceWith, len2, NULL, NULL ); 576 return COMDLG32_FR_DoFindReplace(pdata); 577 } 578