|
|
1.1 root 1: /************************************************************************
2:
3: File: find.c
4:
5: Purpose:
6:
7: Manages CDTEST's find/replace dialog box.
8:
9: Functions:
10:
11: - lpfnFilterProc() -- A callback function for a filter that must be
12: installed if a modeless dialog is created with
13: another dialog as its parent.
14:
15: - DoFindDialog() -- Creates CDTEST's Open/Save dialog.
16:
17: - FindProc() -- Callback function for CDTEST's Find/Replace dlg.
18:
19: - InitFindStruct() -- Fills a FINDREPLACE structure with some defaults.
20:
21: - FillFindDlg() -- Fills CDTESTs Find/Replace dialog with the contents
22: of a FINDREPLACE structure.
23:
24: - GetFindDlg() -- Retrieves the users edit's from CDTEST's find/
25: replace dialog and puts them in a FINDREPLACE
26: structure.
27:
28: - FindReplaceHookProc() -- Callback function for FindText() or ReplaceText()
29: which will be called if either of these dialogs
30: is created with the FR_ENABLEHOOK flag.
31:
32: - GetFindDlgHandle() -- Returns a handle to a preloaded FindText() template.
33:
34: - GetReplaceDlgHandle() -- Returns a handle to a preloaded ReplaceText() template.
35:
36: - DoFindRepStuff() -- Calls FindText() or ReplaceText().
37:
38:
39: NOTE: CDTEST does not multithread the FindText() or the ReplaceText()
40: common dialogs. The reason for this is that since these dialogs
41: are modeless, their creation functions return immediately after the
42: dialogs are created as opposed to other dialog functions that
43: don't return until after the dialog has been destroyed by the user.
44:
45: As a result, any threads that create modeless dialogs will end
46: immediately unless the threads themselves have separate message
47: loops. For the sake of clarity, this functionality has not been
48: added to CDTEST.
49:
50: ************************************************************************/
51:
52:
53: #include <windows.h>
54: #include <commdlg.h>
55: #include <stdlib.h>
56: #include <winnls.h>
57: #include "cdtest.h"
58: #include "find.h"
59: #include "replace.h"
60:
61:
62: /* All functions used in this module + some exported ones */
63:
64: void InitFindStruct(HWND, LPFINDREPLACE) ;
65: void FillFindDlg(HWND, LPFINDREPLACE) ;
66: void GetFindDlg(HWND, LPFINDREPLACE) ;
67: extern UINT uMode ;
68: extern LONG MyAtol(LPTSTR, BOOL, LPBOOL) ;
69: UINT APIENTRY FindReplaceHookProc(HWND, UINT, UINT, LONG) ;
70: void DoFindRepStuff(LPFINDREPLACE) ;
71:
72:
73:
74: /* All global variables used in this module */
75:
76: HWND hwndFind ;
77: HWND hwndMainDialog ;
78:
79: FINDREPLACE fr ;
80: LPFINDREPLACE lpFr ;
81:
82: TCHAR szFindWhat[100] ;
83: TCHAR szReplaceWith[100] ;
84: TCHAR szTemplate[40] ;
85:
86: HANDLE hResFind, hDialogFind ;
87: HANDLE GetFindDlgHandle(void) ;
88: HANDLE GetReplaceDlgHandle(void) ;
89:
90: HBRUSH hBrushDlg ;
91: HBRUSH hBrushEdit ; //brush handles for new colors done with hook proc
92: HBRUSH hBrushButton ;
93:
94:
95:
96:
97:
98: /************************************************************************
99:
100: Function: lpfnFilterProc(int, WPARAM, LAPRAM)
101:
102: Purpose: This is needed if a modeless dialog is created with its parent
103: as another dialog box.
104:
105:
106: Returns: TRUE if the message was handled and FALSE if not.
107:
108: Comments:
109:
110: The reason for this is that the DialogBox() procedure does not call
111: the IsDialogMessage() function before it processes messages, so we
112: need to install a hook function to do it for us.
113:
114: ************************************************************************/
115:
116:
117: LRESULT CALLBACK lpfnFilterProc(int nCode, WPARAM wParam, LPARAM lParam)
118: {
119: static bFirstTime = TRUE ;
120:
121: if (nCode < 0)
122: return CallNextHookEx(hHook, nCode, wParam, lParam) ;
123:
124: if (nCode == MSGF_DIALOGBOX && bFirstTime)
125: {
126: bFirstTime = FALSE ;
127:
128: if (hwndFind && IsDialogMessage(hwndFind, (LPMSG) lParam))
129: {
130: bFirstTime = TRUE ;
131: return 1L ;
132: }
133:
134: else
135: {
136: bFirstTime = TRUE ;
137: return 0L ;
138: }
139: }
140: else return 0L ;
141: }
142:
143:
144:
145:
146:
147:
148:
149: /************************************************************************
150:
151: Function: DoFindDialog(HWND)
152:
153: Purpose: This function installs the Hook function, creates the Find/
154: Replace dialog, and un-installs the Hook.
155:
156: Returns: Nothing.
157:
158: Comments:
159:
160: ************************************************************************/
161:
162: void DoFindDialog(HWND hwnd)
163: {
164: bDoFindDlg = TRUE ;
165:
166: /* this is a little different than the others. If the dialog is just
167: created normally, it will make no IsDlgMessage() checks and the
168: find/replace dialogs will have no keyboard input (i.e. tabbing and
169: alt+key-ing from control to control. To fix this, a message hook
170: and message filter have to be installed
171:
172: It must be set to only look at the input for the current thread, or other
173: programs will be interrupted by this hook also.
174: */
175:
176: hHook = SetWindowsHookEx(WH_MSGFILTER, lpfnFilterProc,
177: hInst, GetCurrentThreadId()) ;
178:
179: if (!hHook) return ;
180:
181: DialogBox(hInst, MAKEINTRESOURCE(ID_FINDDIALOG), hwnd, FindProc) ;
182:
183: UnhookWindowsHookEx(hHook) ;
184:
185: }
186:
187:
188:
189:
190:
191:
192:
193: /************************************************************************
194:
195: Function: FindProc(HWND, UINT, UINT, LONG)
196:
197: Purpose: This is the callback function for the CDTEST's Find/Replace
198: Dialog.
199:
200: Returns: TRUE or FALSE depending on the situation.
201:
202: Comments:
203:
204: ************************************************************************/
205:
206: BOOL APIENTRY FindProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
207: {
208: switch (msg)
209: {
210: case WM_INITDIALOG:
211:
212: if (bDoFindDlg)
213: SetWindowText(hwnd, TEXT("FindText()")) ;
214: else
215: SetWindowText(hwnd, TEXT("ReplaceText()")) ;
216:
217: InitFindStruct(hwnd, &fr) ;
218: FillFindDlg(hwnd, &fr) ;
219:
220: hwndMainDialog = hwnd ;
221:
222:
223: /* The find and replace dialogs are a lot harder to multithread because they
224: are modeless. Modeless dialog creation functions return right after the
225: dialog is created. Since ExitThread will be called at this point, it is
226: probably not possible to multithread these dialogs without a separate
227: GetMessage() loop.
228: */
229:
230:
231: EnableWindow(GetDlgItem(hwnd, ID_MULTITHREADFINDREP), FALSE) ;
232:
233: SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEFT)) ;
234:
235: break ;
236:
237:
238: case WM_COMMAND:
239: {
240: switch (LOWORD(wParam))
241: {
242: case IDOK:
243: GetFindDlg(hwnd, &fr) ;
244: DoFindRepStuff(&fr) ;
245: break ;
246:
247: case ID_RESETFIND:
248: SendDlgItemMessage(hwnd, ID_FRNULLSTRUCT, BM_SETCHECK, (WPARAM)0, (LPARAM)0) ;
249: SendDlgItemMessage(hwnd, ID_PRELOADEDFIND, BM_SETCHECK, (WPARAM)0, (LPARAM)0) ;
250: InitFindStruct(hwnd, &fr) ;
251: FillFindDlg(hwnd, &fr) ;
252: SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEFT)) ;
253: break ;
254:
255: case IDCANCEL:
256: EndDialog(hwnd, FALSE) ;
257:
258: break ;
259:
260:
261: default: break ;
262: }
263:
264: }
265:
266: default:
267:
268:
269: /* nFindMsg is registered at program startup (see CDTEST.c). The
270: FindText() and ReplaceText() dialogs will communicate with the
271: calling application via this message. */
272:
273: if (msg == nFindMsg)
274: {
275: lpFr = (LPFINDREPLACE) lParam ;
276:
277: if (lpFr->Flags & FR_DIALOGTERM)
278: {
279: PostMessage(hwnd, UMSG_DECREMENTDLGCOUNT, 0, 0L) ;
280:
281: if (hDialogFind)
282: {
283: FreeResource(hDialogFind) ;
284: hDialogFind = (HANDLE) 0 ;
285: hResFind = (HANDLE) 0 ;
286: }
287:
288: hwndFind = (HWND) 0 ;
289: }
290:
291: FillFindDlg(hwnd, &fr) ;
292:
293: wsprintf(szTemp, szLongFilter, CommDlgExtendedError()) ;
294: SetDlgItemText(hwnd, ID_ERRORFT, szTemp) ;
295:
296: wsprintf(szTemp, szLongFilter, hwndFind) ;
297: SetDlgItemText(hwnd, ID_RETURNFT, szTemp) ;
298: }
299:
300:
301: /* If the help button is pressed in the FindText() or ReplaceText()
302: dialogs, it will send a message Registered with RegisterWindowMessage()
303: to the parent window. The message nHelpMessage was registered
304: at application startup */
305:
306: if (msg == nHelpMessage)
307: MessageBox(GetForegroundWindow(), TEXT("Hello from the help button"),
308: TEXT("Find Help Button"), MB_OK | MB_APPLMODAL) ;
309:
310: break ;
311: }
312:
313: return FALSE ;
314: }
315:
316:
317:
318:
319:
320:
321: /************************************************************************
322:
323: Function: InitFindStruct(HWND, LPFINDREPLACE)
324:
325: Purpose: Fills a FINDREPLACE structure with some defaults.
326:
327:
328: Returns: Nothing.
329:
330: Comments:
331:
332: ************************************************************************/
333:
334: void InitFindStruct(HWND hwnd, LPFINDREPLACE pfr)
335: {
336: pfr->lStructSize = (DWORD) sizeof(FINDREPLACE) ;
337: pfr->hwndOwner = hwnd ;
338: pfr->hInstance = (HANDLE) hInst ;
339: pfr->Flags = FR_DOWN | FR_SHOWHELP ;
340:
341: lstrcpy(szFindWhat, TEXT("Word to find")) ;
342: pfr->lpstrFindWhat = szFindWhat ;
343: pfr->wFindWhatLen = 100 ;
344:
345: lstrcpy(szReplaceWith, TEXT("Replace with word")) ;
346: pfr->lpstrReplaceWith = szReplaceWith ;
347: pfr->wReplaceWithLen = 100 ;
348:
349: pfr->lCustData = (DWORD) 0 ;
350:
351: pfr->lpfnHook = FindReplaceHookProc ;
352:
353: lstrcpy(szTemplate, TEXT("fttemp1")) ;
354:
355: pfr->lpTemplateName = szTemplate ;
356: }
357:
358:
359:
360:
361:
362:
363: /************************************************************************
364:
365: Function: FillFindDlg(HWND, LPFINDREPLACE)
366:
367: Purpose: Fills CDTEST's Find/Replace dialog with the contents of a
368: FINDREPLACE structure.
369:
370: Returns: Nothing.
371:
372: Comments:
373:
374: ************************************************************************/
375:
376: void FillFindDlg(HWND hwnd, LPFINDREPLACE pfr)
377: {
378: wsprintf(szTemp, szLongFilter, pfr->lStructSize) ;
379: SetDlgItemText(hwnd, ID_STRUCTSIZEFT, szTemp) ;
380:
381: wsprintf(szTemp, szLongFilter, (DWORD) pfr->hwndOwner) ;
382: SetDlgItemText(hwnd, ID_HWNDOWNERFT, szTemp) ;
383:
384: wsprintf(szTemp, szLongFilter, (DWORD) pfr->hInstance) ;
385: SetDlgItemText(hwnd, ID_HINSTANCEFT, szTemp) ;
386:
387: wsprintf(szTemp, szLongFilter, pfr->Flags) ;
388: SetDlgItemText(hwnd, ID_FLAGSFT, szTemp) ;
389:
390: SetDlgItemText(hwnd, ID_FINDWHATFT, pfr->lpstrFindWhat) ;
391:
392: wsprintf(szTemp, szLongFilter, pfr->wFindWhatLen) ;
393: SetDlgItemText(hwnd, ID_FINDWHATLENFT, szTemp) ;
394:
395: SetDlgItemText(hwnd, ID_REPLACEWITHFT, pfr->lpstrReplaceWith) ;
396:
397: wsprintf(szTemp, szLongFilter, pfr->wReplaceWithLen) ;
398: SetDlgItemText(hwnd, ID_REPLACEWITHLENFT, szTemp) ;
399:
400: wsprintf(szTemp, szLongFilter, pfr->lCustData) ;
401: SetDlgItemText(hwnd, ID_CUSTDATAFT, szTemp) ;
402:
403: wsprintf(szTemp, szLongFilter, (DWORD) pfr->lpfnHook) ;
404: SetDlgItemText(hwnd, ID_HOOKFT, szTemp) ;
405:
406: SetDlgItemText(hwnd, ID_TEMPLATEFT, pfr->lpTemplateName) ;
407: }
408:
409:
410:
411:
412:
413:
414: /************************************************************************
415:
416: Function: GetFindDlg(HWND, LPFINDREPLACE)
417:
418: Purpose: Fills a FINDREPLACE structure with the user's edits in CDTEST's
419: Find/Replace dialog.
420:
421: Returns: Nothing.
422:
423: Comments:
424:
425: ************************************************************************/
426:
427: void GetFindDlg(HWND hwnd, LPFINDREPLACE pfr)
428: {
429: TCHAR szNum[30] ;
430: BOOL b ;
431:
432: #define WSIZEFR 30
433:
434: GetDlgItemText(hwnd, ID_STRUCTSIZEFT, szNum, WSIZEFR) ;
435: pfr->lStructSize = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
436:
437: GetDlgItemText(hwnd, ID_HWNDOWNERFT, szNum, WSIZEFR) ;
438: pfr->hwndOwner = (HWND) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
439:
440: GetDlgItemText(hwnd, ID_HINSTANCEFT, szNum, WSIZEFR) ;
441: pfr->hInstance = (HANDLE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
442:
443: GetDlgItemText(hwnd, ID_FLAGSFT, szNum, WSIZEFR) ;
444: pfr->Flags = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
445:
446:
447: GetDlgItemText(hwnd, ID_FINDWHATFT, szFindWhat, 100) ;
448:
449: GetDlgItemText(hwnd, ID_REPLACEWITHFT, szReplaceWith, 100) ;
450:
451:
452: GetDlgItemText(hwnd, ID_FINDWHATLENFT, szNum, WSIZEFR) ;
453: pfr->wFindWhatLen = (WORD) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
454:
455: GetDlgItemText(hwnd, ID_REPLACEWITHLENFT, szNum, WSIZEFR) ;
456: pfr->wReplaceWithLen = (WORD) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
457:
458: GetDlgItemText(hwnd, ID_CUSTDATAFT, szNum, WSIZEFR) ;
459: pfr->lCustData = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
460:
461: GetDlgItemText(hwnd, ID_HOOKFT, szNum, WSIZEFR) ;
462: pfr->lpfnHook = (LPFRHOOKPROC) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
463:
464: GetDlgItemText(hwnd, ID_TEMPLATEFT, szTemplate, 40) ;
465: }
466:
467:
468:
469:
470:
471:
472: /************************************************************************
473:
474: Function: FindReplaceHookProc(HWND, UINT, UINT, LONG)
475:
476: Purpose: Is the callback function that will be called by FindText()
477: or ReplaceText() if the function is called with the
478: FR_ENABLEHOOK flag.
479:
480:
481: Returns: TRUE to discard the message, and FALSE to instruct the common
482: dialogs to process the message with the default logic.
483:
484: Comments:
485:
486: NOTE!
487:
488: If the application returns FALSE in response to the WM_INITDIALOG
489: message, it is then responsible for displaying the dialog by
490: calling ShowWindow() and UpdateWindow().
491:
492: ***********************************************************************/
493:
494:
495: UINT APIENTRY FindReplaceHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
496: {
497: LPFINDREPLACE pFr ;
498: TCHAR szMsg[75] ;
499: TCHAR szTmp[20] ;
500: int i ;
501: TCHAR szDefString[] = TEXT("Default String ") ;
502:
503: switch(msg)
504: {
505: case WM_INITDIALOG:
506:
507: pFr = (LPFINDREPLACE) lParam ;
508:
509: if (pFr->lCustData != 0L)
510: {
511: wsprintf(szMsg, TEXT("FINDREPLACE->lCustData is: %ld"), pFr->lCustData) ;
512:
513: MessageBox(hwnd, szMsg, TEXT("lCustData Sent!"), MB_OK | MB_APPLMODAL) ;
514: }
515:
516: SetWindowText(hwnd, TEXT("Find Hook Proc Dialog")) ;
517:
518: if (GetDlgItem(hwnd, ID_DEFSTRINGS))
519: {
520: for (i=0; i<5; i++)
521: {
522: lstrcpy(szMsg, szDefString) ;
523: wsprintf(szTmp, TEXT("Number %d"), i+1) ;
524: lstrcat(szMsg, szTmp) ;
525: SendDlgItemMessage(hwnd, ID_DEFSTRINGS, LB_ADDSTRING, (WPARAM) 0,
526: (LONG) (LPTSTR) szMsg) ;
527: }
528: }
529:
530: return TRUE ;
531:
532: break ;
533:
534:
535:
536: /* use the WM_CTLCOLOR* messages to change the color of the Open
537: dialog */
538:
539: case WM_CTLCOLORDLG:
540:
541: if (!hBrushDlg)
542: hBrushDlg = GetStockObject(LTGRAY_BRUSH) ;
543:
544: return (UINT) hBrushDlg ;
545:
546: break ;
547:
548:
549: case WM_CTLCOLORBTN:
550:
551: SetBkMode((HDC) wParam, TRANSPARENT) ; //sets background color
552: //for push and check box
553: //buttons...
554:
555: if (!hBrushButton)
556: hBrushButton = GetStockObject(LTGRAY_BRUSH) ;
557:
558: return (UINT) hBrushButton ;
559:
560: break ;
561:
562:
563: case WM_CTLCOLORSTATIC:
564:
565: SetTextColor((HDC) wParam, RGB(0x00, 0xff, 0x00)) ; //green
566: SetBkMode((HDC) wParam, TRANSPARENT) ; //transparent text
567:
568: if (!hBrushDlg)
569: hBrushDlg = GetStockObject(LTGRAY_BRUSH) ;
570:
571: return (UINT) hBrushDlg ;
572:
573: break ;
574:
575:
576: default:
577: break ;
578: }
579:
580: return FALSE ; //send msg to the common dialog code
581: }
582:
583:
584:
585:
586:
587:
588:
589:
590:
591: /************************************************************************
592:
593: Function: GetFindDlgHandle(void)
594:
595: Purpose: Finds, loads, and returns a handle to the custom template
596: for FindText() in CDTEST.EXE.
597:
598: Returns: HANDLE to the dialog resource.
599:
600: Comments:
601:
602: ************************************************************************/
603:
604: HANDLE GetFindDlgHandle(void)
605: {
606: hResFind = FindResource(hInst, TEXT("fttemp1"), RT_DIALOG) ;
607:
608: hDialogFind = LoadResource(hInst, hResFind) ;
609:
610:
611: return hDialogFind ;
612: }
613:
614:
615:
616:
617:
618: /************************************************************************
619:
620: Function: GetReplaceDlgHandle(void)
621:
622: Purpose: Finds, loads, and returns a handle to the custom template
623: for ReplaceText() in CDTEST.EXE.
624:
625: Returns: HANDLE to the dialog resource.
626:
627: Comments:
628:
629: ************************************************************************/
630:
631: HANDLE GetReplaceDlgHandle(void)
632: {
633: hResFind = FindResource(hInst, TEXT("fttemp2"), RT_DIALOG) ;
634:
635: hDialogFind = LoadResource(hInst, hResFind) ;
636:
637: return hDialogFind ;
638: }
639:
640:
641:
642:
643:
644:
645: /************************************************************************
646:
647: Function: DoFindReplaceStuff(LPFINDREPLACE)
648:
649: Purpose: Calls FindText() or ReplaceText().
650:
651: Returns: Nothing:
652:
653: Comments:
654:
655: ************************************************************************/
656:
657: void DoFindRepStuff(LPFINDREPLACE pfr)
658: {
659: if (IsDlgButtonChecked(hwndMainDialog, ID_PRELOADEDFIND) == 1)
660: {
661: if (bDoFindDlg)
662: pfr->hInstance = GetFindDlgHandle() ;
663: else
664: pfr->hInstance = GetReplaceDlgHandle() ;
665: }
666:
667: if (bDoFindDlg)
668: {
669: if (IsDlgButtonChecked(hwndMainDialog, ID_FRNULLSTRUCT) == 1)
670: {
671: hwndFind = FindText((LPFINDREPLACE) NULL) ;
672: }
673: else
674: {
675: hwndFind = FindText(pfr) ;
676: }
677: }
678: else
679: {
680: if (IsDlgButtonChecked(hwndMainDialog, ID_FRNULLSTRUCT) == 1)
681: {
682: hwndFind = ReplaceText((LPFINDREPLACE) NULL) ;
683: }
684: else
685: {
686: hwndFind = ReplaceText(pfr) ;
687: }
688:
689: }
690:
691:
692: wsprintf(szTemp, szLongFilter, CommDlgExtendedError()) ;
693: SetDlgItemText(hwndMainDialog, ID_ERRORFT, szTemp) ;
694:
695: wsprintf(szTemp, szLongFilter, hwndFind) ;
696: SetDlgItemText(hwndMainDialog, ID_RETURNFT, szTemp) ;
697: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.