|
|
1.1 ! root 1: ! 2: /*************************************************************************/ ! 3: /* */ ! 4: /* NT-based multithreaded file browser */ ! 5: /* Ruediger R. Asche */ ! 6: /* Copyright (c) 1992,1993 Microsoft Corporation */ ! 7: /* */ ! 8: /*************************************************************************/ ! 9: ! 10: /*************************************************************************/ ! 11: /* */ ! 12: /* Description: */ ! 13: /* This file manager extension will perform the following: */ ! 14: /* - user clicks "search". This will open the target window */ ! 15: /* which has an edit control embedded in it and send a */ ! 16: /* WM_LAUNCH message to that window. */ ! 17: /* - The window function then dispatches the "master thread" */ ! 18: /* which will, in turn, dispatch a new thread for every */ ! 19: /* file selected by the user. The master thread waits until */ ! 20: /* all file threads have finished, then send a WM_FREEAGAIN */ ! 21: /* message to the main window which will then display the */ ! 22: /* results and clean up. */ ! 23: /* */ ! 24: /*************************************************************************/ ! 25: ! 26: ! 27: /*************************************************************************/ ! 28: /* */ ! 29: /* Includes */ ! 30: /* */ ! 31: /*************************************************************************/ ! 32: ! 33: ! 34: extern "C" ! 35: { ! 36: #include <windows.h> ! 37: #include <string.h> ! 38: #include <ctype.h> ! 39: #include <stdlib.h> ! 40: #include "guigrep.h" ! 41: #include "wfext.h" ! 42: } ! 43: ! 44: /*************************************************************************/ ! 45: /* */ ! 46: /* Global variables */ ! 47: /* */ ! 48: /*************************************************************************/ ! 49: ! 50: memory *MasterBlock; ! 51: growmemory *ResultBlock; ! 52: HWND hWndGlobal; ! 53: int iHitCount=0; ! 54: char szGlobalSearchString[MAXLINELEN]; ! 55: unsigned int iGlobalSStLen; ! 56: int iFinishedFiles; ! 57: BOOL bCaseInsens=FALSE; ! 58: HINSTANCE hOurselves; ! 59: WNDPROC lpfnOldEditProc; ! 60: char lpszCRLF[]="\r\n"; ! 61: int ilpszCRLF = strlen("\r\n"); ! 62: BOOL bObjectExists = FALSE; ! 63: ! 64: /*************************************************************************/ ! 65: /* */ ! 66: /* Symbolic equals. */ ! 67: /* */ ! 68: /*************************************************************************/ ! 69: ! 70: #define WNDCLASSNAME "SearchWndClass" ! 71: ! 72: /*************************************************************************/ ! 73: /* */ ! 74: /* Forward function declarations */ ! 75: /* */ ! 76: /*************************************************************************/ ! 77: ! 78: ! 79: BOOL APIENTRY About( ! 80: HWND hDlg, ! 81: UINT message, ! 82: UINT wParam, ! 83: LONG lParam); ! 84: ! 85: ! 86: ! 87: long Poll_On_Threads(LONG lParam); ! 88: ! 89: ! 90: /*************************************************************************/ ! 91: /* */ ! 92: /* A generic window class that carries an edit child in its entire */ ! 93: /* client area wherever it goes. */ ! 94: /* */ ! 95: /*************************************************************************/ ! 96: ! 97: ! 98: LONG APIENTRY ColorWndProc( ! 99: HWND hWnd, ! 100: UINT message, ! 101: UINT wParam, ! 102: LONG lParam) ! 103: { ! 104: static char szBuf[13]; ! 105: static char szPathName[MAX_PATH]; ! 106: ! 107: RECT rcClient; ! 108: static HWND hWndHitBox,hWndFileMan; ! 109: HINSTANCE hInst = (HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE); ! 110: switch (message) { ! 111: case WM_CREATE: ! 112: AppendMenu(GetSystemMenu(hWnd,FALSE),MF_STRING, IDM_ABOUT, "About..."); ! 113: hWndHitBox = CreateWindow("EDIT","",WS_CHILD | WS_VISIBLE | ES_WANTRETURN | ES_AUTOHSCROLL | ! 114: DS_LOCALEDIT|ES_MULTILINE | WS_BORDER|WS_VSCROLL|WS_HSCROLL, ! 115: 0,0,1,1,hWnd, NULL, hInst, ! 116: NULL); ! 117: if (!hWndHitBox) ! 118: {MessageBox(hWnd,"Unable to create Child Window!","Browse Extension",MB_OK); ! 119: return(-1); ! 120: }; ! 121: ! 122: CloseHandle((HANDLE)SendMessage(hWndHitBox,EM_GETHANDLE,0,0)); ! 123: ShowWindow(hWndHitBox,SW_SHOWNORMAL); ! 124: break; ! 125: case WM_SIZE: ! 126: GetClientRect(hWnd,&rcClient); ! 127: MoveWindow(hWndHitBox,rcClient.left,rcClient.top, ! 128: rcClient.right, rcClient.bottom, TRUE); ! 129: break; ! 130: case WM_LAUNCH: ! 131: hWndFileMan = (HWND)lParam; ! 132: { static THREADPBLOCK tpbParms; ! 133: int iPollThreadID; ! 134: tpbParms.hWndGlobal = hWnd; ! 135: tpbParms.hWndFileBox = hWndFileMan; ! 136: SendMessage(hWndHitBox,LB_RESETCONTENT,0,0); ! 137: ResultBlock = new growmemory(4*4096,4096); ! 138: bObjectExists=TRUE; ! 139: HANDLE hNewThread=CreateThread(NULL,0, ! 140: (LPTHREAD_START_ROUTINE)Poll_On_Threads,(LPVOID)&tpbParms,0,(LPDWORD)&iPollThreadID); ! 141: }; ! 142: break; ! 143: case WM_ADDITEM: ! 144: { char szBuf[40]; ! 145: wsprintf(szBuf,"Finished %d File(s)",(int)lParam); ! 146: SetWindowText(hWnd,szBuf); ! 147: }; ! 148: break; ! 149: case WM_FREEAGAIN: ! 150: SendMessage(hWndHitBox,EM_SETHANDLE,(WPARAM)ResultBlock->GetHandle(),0); ! 151: InvalidateRect(hWndHitBox,NULL,FALSE); ! 152: break; ! 153: ! 154: case WM_SYSCOMMAND: ! 155: if (wParam == IDM_ABOUT) ! 156: DialogBox(hOurselves, ! 157: "AboutBox", ! 158: hWnd, ! 159: (DLGPROC)About); ! 160: else ! 161: return (DefWindowProc(hWnd, message, wParam, lParam)); ! 162: break; ! 163: ! 164: case WM_DESTROY: ! 165: bObjectExists=FALSE; ! 166: delete(ResultBlock); ! 167: break; ! 168: default: ! 169: return (DefWindowProc(hWnd, message, wParam, lParam)); ! 170: } ! 171: return (NULL); ! 172: } ! 173: ! 174: ! 175: /*************************************************************************/ ! 176: /* */ ! 177: /* The inevitable about box... */ ! 178: /* */ ! 179: /*************************************************************************/ ! 180: ! 181: ! 182: BOOL APIENTRY About( ! 183: HWND hDlg, ! 184: UINT message, ! 185: WPARAM wParam, ! 186: LPARAM lParam) ! 187: { ! 188: switch (message) { ! 189: case WM_INITDIALOG: ! 190: return (TRUE); ! 191: ! 192: case WM_COMMAND: ! 193: if (LOWORD(wParam) == IDOK ! 194: || LOWORD(wParam) == IDCANCEL) { ! 195: EndDialog(hDlg, TRUE); ! 196: return (TRUE); ! 197: } ! 198: break; ! 199: } ! 200: return (FALSE); ! 201: UNREFERENCED_PARAMETER(lParam); ! 202: } ! 203: ! 204: /*************************************************************************/ ! 205: /* */ ! 206: /* The DLL Entry and exit dispatcher. */ ! 207: /* */ ! 208: /*************************************************************************/ ! 209: ! 210: ! 211: ! 212: extern "C" ! 213: { ! 214: BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) ! 215: { ! 216: switch (dwReason) ! 217: { ! 218: case DLL_PROCESS_ATTACH: ! 219: { ! 220: WNDCLASS wc; ! 221: hOurselves=hDLL; ! 222: ! 223: wc.style = NULL; ! 224: wc.lpfnWndProc = (WNDPROC)ColorWndProc; ! 225: wc.cbClsExtra = 0; ! 226: wc.cbWndExtra = 0; ! 227: wc.hInstance = (HINSTANCE)GetCurrentProcess(); ! 228: wc.hIcon = LoadIcon(hDLL, "GrepIcon"); ! 229: wc.hCursor = LoadCursor(NULL,IDC_ARROW); ! 230: wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); ! 231: wc.lpszMenuName = NULL; ! 232: wc.lpszClassName = WNDCLASSNAME; ! 233: ! 234: if (!RegisterClass(&wc)) ! 235: { ! 236: MessageBox(GetFocus(),"Unable to create class", ! 237: "Browse extension",MB_OK); ! 238: return(NULL); ! 239: } ! 240: }; ! 241: }; ! 242: return( TRUE ); ! 243: } ! 244: } ! 245: ! 246: /*************************************************************************/ ! 247: /* */ ! 248: /* Dialog box function for the "Select string" dialog */ ! 249: /* */ ! 250: /*************************************************************************/ ! 251: ! 252: ! 253: ! 254: BOOL APIENTRY StringProc( ! 255: HWND hDlg, ! 256: UINT message, ! 257: WPARAM wParam, ! 258: LPARAM lParam) ! 259: { HWND hEditControl; ! 260: switch (message) ! 261: { ! 262: case WM_INITDIALOG: ! 263: hEditControl = GetDlgItem(hDlg, IDM_STRINGEDIT); ! 264: SetWindowText(hEditControl,szGlobalSearchString); ! 265: SendMessage(GetDlgItem(hDlg,IDM_CASESENS),BM_SETCHECK,bCaseInsens,0); ! 266: return (TRUE); ! 267: ! 268: case WM_COMMAND: ! 269: switch (LOWORD(wParam)) ! 270: { ! 271: case IDM_CANCEL: ! 272: EndDialog(hDlg,FALSE); ! 273: return(TRUE); ! 274: break; ! 275: case IDM_TERMBOX: ! 276: {int iLoopVar, iLen; ! 277: bCaseInsens = SendMessage(GetDlgItem(hDlg,IDM_CASESENS),BM_GETCHECK,0,0); ! 278: hEditControl = GetDlgItem(hDlg,IDM_STRINGEDIT); ! 279: GetWindowText(hEditControl,szGlobalSearchString,MAXLINELEN); ! 280: if (bCaseInsens) ! 281: { iLen = strlen(szGlobalSearchString); ! 282: for (iLoopVar = 0; iLoopVar < iLen;iLoopVar++) ! 283: if (IsCharUpper(szGlobalSearchString[iLoopVar])) ! 284: szGlobalSearchString[iLoopVar] = (char)_tolower((int)szGlobalSearchString[iLoopVar]); ! 285: }; ! 286: EndDialog(hDlg, TRUE); ! 287: } ! 288: break; ! 289: ! 290: } ! 291: break; ! 292: } ! 293: return (FALSE); ! 294: UNREFERENCED_PARAMETER(lParam); ! 295: } ! 296: ! 297: ! 298: long TraverseFileCaseInsens(HANDLE hFile, LPSTR lpFilNam, LPSTR lpFileView) ! 299: { ! 300: unsigned int iGlobalSearchString, iCurrentBuffPt, iPrefixLength; ! 301: BOOL bMatch; ! 302: LPSTR lpLineBuff; ! 303: unsigned int iLineCt = 0; ! 304: DWORD dwFileSize, dwCurrentFilePt; ! 305: ! 306: dwFileSize = GetFileSize(hFile,NULL); ! 307: lpLineBuff = MasterBlock->Alloc(MAXLINELEN); ! 308: if (!lpLineBuff) ! 309: { ! 310: MessageBox(GetFocus(),lpFilNam,"Out of memory processing:",MB_OK); ! 311: return (-1); ! 312: }; ! 313: /**************************************************************************/ ! 314: /* Initialize variables: */ ! 315: /* lpLineBuff contains the buffer in which we store the whole line. */ ! 316: /* If the line doesn't match, we "recycle" the buffer by using it */ ! 317: /* for the next line; if it does, we send it off. */ ! 318: /* iCurrentBuff is the length of the line we currently work on, */ ! 319: /* and iGlobalSearchString describes how far in the global search */ ! 320: /* string we have progreesed so far matching. */ ! 321: /**************************************************************************/ ! 322: ! 323: strcpy(lpLineBuff,lpFilNam); ! 324: strcat(lpLineBuff," < >: "); ! 325: iPrefixLength = strlen(lpLineBuff); ! 326: iCurrentBuffPt = iPrefixLength-1; ! 327: iGlobalSearchString = 0; ! 328: bMatch = FALSE; ! 329: /**************************************************************************/ ! 330: /* Now go through the mapping character by character */ ! 331: /**************************************************************************/ ! 332: ! 333: for (dwCurrentFilePt=0; ! 334: dwCurrentFilePt<dwFileSize; ! 335: dwCurrentFilePt++) ! 336: ! 337: { if (iCurrentBuffPt >= MAXLINELEN) ! 338: {MessageBox(GetFocus(),"File not readable!",lpFilNam,MB_OK); ! 339: return(-1); ! 340: }; ! 341: ! 342: iCurrentBuffPt++; ! 343: lpLineBuff[iCurrentBuffPt]= lpFileView[dwCurrentFilePt]; ! 344: if (lpLineBuff[iCurrentBuffPt] == '\n') ! 345: { ! 346: ! 347: iLineCt++; ! 348: if (bMatch) ! 349: { ! 350: /**************************************************************************/ ! 351: /* A match has occurred! */ ! 352: /* At this point, lpLineBuff points to the string that contains the */ ! 353: /* matching line; iCurrentBuffPt its length. */ ! 354: /**************************************************************************/ ! 355: ! 356: OemToChar(lpLineBuff,lpLineBuff); ! 357: wsprintf(&lpLineBuff[strlen(lpFilNam)+2],"%4d",iLineCt); ! 358: lpLineBuff[strlen(lpFilNam)+6] = '>'; ! 359: iHitCount++; ! 360: ResultBlock->add(lpLineBuff,iCurrentBuffPt-1); ! 361: strcpy(lpLineBuff, lpFilNam); ! 362: wsprintf(&lpLineBuff[strlen(lpFilNam)]," < >: "); ! 363: ! 364: }; ! 365: /**************************************************************************/ ! 366: /* The FOR-logic will increment the pointer, */ ! 367: /* so we reduce it by one because we use it in the NEXT iteration. */ ! 368: /**************************************************************************/ ! 369: ! 370: iCurrentBuffPt = iPrefixLength -1; ! 371: iGlobalSearchString = 0; ! 372: bMatch = FALSE; ! 373: } ! 374: else ! 375: ! 376: { if (iGlobalSearchString < iGlobalSStLen) ! 377: if ( /* This is the only difference to case-sensitive... */ ! 378: (IsCharUpper(lpLineBuff[iCurrentBuffPt]) ? (char)_tolower(lpLineBuff[iCurrentBuffPt]) ! 379: : lpLineBuff[iCurrentBuffPt]) == szGlobalSearchString[iGlobalSearchString]) ! 380: { iGlobalSearchString++; ! 381: bMatch = TRUE; ! 382: } ! 383: else ! 384: { bMatch = FALSE; ! 385: iGlobalSearchString = 0; ! 386: ! 387: }; ! 388: ! 389: }; ! 390: ! 391: }; ! 392: return(TRUE); ! 393: } ! 394: ! 395: /**************************************************************************/ ! 396: /* The case sensitive traversal function is basically the same */ ! 397: /* as the case-insensitive one, just one line difference. */ ! 398: /* The reason why we separate this is that at runtime it is much more */ ! 399: /* efficient not to have to test for case-insensitivity on each and */ ! 400: /* every character we test... */ ! 401: /**************************************************************************/ ! 402: ! 403: ! 404: long TraverseFileCaseSens(HANDLE hFile, LPSTR lpFilNam, LPSTR lpFileView) ! 405: { ! 406: unsigned int iGlobalSearchString, iCurrentBuffPt, iPrefixLength; ! 407: BOOL bMatch; ! 408: LPSTR lpLineBuff; ! 409: unsigned int iLineCt = 0; ! 410: DWORD dwFileSize, dwCurrentFilePt; ! 411: ! 412: dwFileSize = GetFileSize(hFile,NULL); ! 413: lpLineBuff = MasterBlock->Alloc(MAXLINELEN); ! 414: if (!lpLineBuff) ! 415: { ! 416: MessageBox(GetFocus(),lpFilNam,"Out of memory processing:",MB_OK); ! 417: return (-1); ! 418: }; ! 419: ! 420: strcpy(lpLineBuff,lpFilNam); ! 421: strcat(lpLineBuff," < >: "); ! 422: iPrefixLength = strlen(lpLineBuff); ! 423: iCurrentBuffPt = iPrefixLength-1; ! 424: iGlobalSearchString = 0; ! 425: bMatch = FALSE; ! 426: for (dwCurrentFilePt=0; ! 427: dwCurrentFilePt<dwFileSize; ! 428: dwCurrentFilePt++) ! 429: ! 430: { if (iCurrentBuffPt >= MAXLINELEN) ! 431: {MessageBox(GetFocus(),"File not readable!",lpFilNam,MB_OK); ! 432: return(-1); ! 433: }; ! 434: ! 435: iCurrentBuffPt++; ! 436: lpLineBuff[iCurrentBuffPt]= lpFileView[dwCurrentFilePt]; ! 437: if (lpLineBuff[iCurrentBuffPt] == '\n') ! 438: { ! 439: ! 440: iLineCt++; ! 441: if (bMatch) ! 442: { ! 443: OemToChar(lpLineBuff,lpLineBuff); ! 444: wsprintf(&lpLineBuff[strlen(lpFilNam)+2],"%4d",iLineCt); ! 445: lpLineBuff[strlen(lpFilNam)+6] = '>'; ! 446: iHitCount++; ! 447: ResultBlock->add(lpLineBuff,iCurrentBuffPt-1); ! 448: strcpy(lpLineBuff, lpFilNam); ! 449: wsprintf(&lpLineBuff[strlen(lpFilNam)]," < >: "); ! 450: ! 451: }; ! 452: iCurrentBuffPt = iPrefixLength -1; ! 453: iGlobalSearchString = 0; ! 454: bMatch = FALSE; ! 455: } ! 456: else ! 457: ! 458: { if (iGlobalSearchString < iGlobalSStLen) ! 459: if (lpLineBuff[iCurrentBuffPt] == szGlobalSearchString[iGlobalSearchString]) ! 460: { iGlobalSearchString++; ! 461: bMatch = TRUE; ! 462: } ! 463: else ! 464: { bMatch = FALSE; ! 465: iGlobalSearchString = 0; ! 466: ! 467: }; ! 468: ! 469: }; ! 470: ! 471: }; ! 472: ! 473: return(TRUE); ! 474: } ! 475: ! 476: ! 477: ! 478: ! 479: long ProcessFileCommonCode (LPTHREADPBLOCK tpArgs) ! 480: { FMS_GETFILESEL gfsSelection; ! 481: LPSTR lpFilNam; ! 482: HANDLE hFile, hMappedFile; ! 483: LPSTR lpFileView; ! 484: unsigned int iLineCt = 0; ! 485: /**************************************************************************/ ! 486: /* Set up file mapping etc. */ ! 487: /**************************************************************************/ ! 488: SendMessage(tpArgs->hWndFileBox,FM_GETFILESEL,tpArgs->iLoop,(LPARAM)&gfsSelection); ! 489: lpFilNam = MasterBlock->Alloc(1+strlen(gfsSelection.szName)); ! 490: strcpy(lpFilNam,gfsSelection.szName); ! 491: ! 492: if ((hFile = CreateFile(lpFilNam, GENERIC_READ, FILE_SHARE_READ, NULL, ! 493: OPEN_ALWAYS, FILE_ATTRIBUTE_READONLY, NULL)) ! 494: == INVALID_HANDLE_VALUE) ! 495: return(FALSE); ! 496: if (!(hMappedFile = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,0))) ! 497: {MessageBox(GetFocus(),"Could not open file mapping!",lpFilNam,MB_OK); ! 498: return(FALSE); ! 499: }; ! 500: if (!(lpFileView = (LPSTR)MapViewOfFile(hMappedFile,FILE_MAP_READ,0,0,0))) ! 501: {MessageBox(GetFocus(),"Could not map file view",lpFilNam,MB_OK); ! 502: return(FALSE); ! 503: }; ! 504: /**************************************************************************/ ! 505: /* Now traverse file */ ! 506: /**************************************************************************/ ! 507: if (bCaseInsens) ! 508: TraverseFileCaseInsens(hFile,lpFilNam,lpFileView); ! 509: else ! 510: TraverseFileCaseSens(hFile,lpFilNam,lpFileView); ! 511: ! 512: /**************************************************************************/ ! 513: /* Clean up. */ ! 514: /**************************************************************************/ ! 515: ! 516: if (!UnmapViewOfFile(lpFileView)) ! 517: MessageBox(GetFocus(),"UnmapViewOfFile Failure",lpFilNam,MB_OK); ! 518: if (!CloseHandle(hMappedFile)) ! 519: MessageBox(GetFocus(),"CloseHandle Failure...",lpFilNam,MB_OK); ! 520: if (!CloseHandle(hFile)) ! 521: MessageBox(GetFocus(),"CloseHandle Failure...",lpFilNam,MB_OK); ! 522: ! 523: iFinishedFiles++; ! 524: SendMessage(hWndGlobal,WM_ADDITEM,(WPARAM)iHitCount,iFinishedFiles); ! 525: return(1); ! 526: ! 527: } ! 528: ! 529: ! 530: ! 531: /*************************************************************************/ ! 532: /* */ ! 533: /* This is the "master thread." Its only purpose is to */ ! 534: /* dispatch one thread for each file selected, then wait for */ ! 535: /* completition of all threads, and return to the main window. */ ! 536: /* This has been made a separate thread due to possible */ ! 537: /* deadlock conditions that might occurr if it was in the */ ! 538: /* main window function. */ ! 539: /* */ ! 540: /* Since there is no system-provided way to limit the number */ ! 541: /* of threads AND it doesn't make sense to have zillions */ ! 542: /* of threads in the system, there is a mechanism that */ ! 543: /* limits the number of threads to a certain limit (currently */ ! 544: /* 30). Would make sense to devise some kind of a fancy */ ! 545: /* algorithm to compute the number of threads dynamically. */ ! 546: /* */ ! 547: /*************************************************************************/ ! 548: ! 549: ! 550: ! 551: long Poll_On_Threads(LONG lParam) ! 552: { int iLoop, iEndLoop,iThread,iArrayIndex; ! 553: char tempFilBuf[80]; ! 554: static HANDLE aThreads[MAX_CONCURRENT_THREADS]; ! 555: HWND hWndFileBox; ! 556: LPTHREADPBLOCK lpTB = (LPTHREADPBLOCK)lParam; ! 557: iHitCount = 0; ! 558: iFinishedFiles = 0; ! 559: iGlobalSStLen = strlen(szGlobalSearchString); ! 560: hWndFileBox = lpTB->hWndFileBox; ! 561: hWndGlobal = lpTB->hWndGlobal; ! 562: MasterBlock = new memory(150000); ! 563: iEndLoop = SendMessage(hWndFileBox,FM_GETSELCOUNT,0,0); ! 564: if (iEndLoop == 0) ! 565: { MessageBox(hWndFileBox,"No files selected","Browser extension",MB_OK); ! 566: return(0); ! 567: }; ! 568: for (iLoop = 0; iLoop < iEndLoop; iLoop++) ! 569: {HANDLE hNewThread; ! 570: ! 571: if (iLoop < MAX_CONCURRENT_THREADS) ! 572: iArrayIndex = iLoop; ! 573: else ! 574: { ! 575: iArrayIndex = WaitForMultipleObjects( ! 576: MAX_CONCURRENT_THREADS,aThreads,FALSE,INFINITE); ! 577: if (iArrayIndex == -1) ! 578: {MessageBeep(0); ! 579: return(-1); ! 580: }; ! 581: ! 582: CloseHandle(aThreads[iArrayIndex]); ! 583: }; ! 584: lpTB = (LPTHREADPBLOCK)MasterBlock->Alloc(sizeof(THREADPBLOCK)); ! 585: lpTB->hWndFileBox=hWndFileBox; ! 586: lpTB->iLoop = iLoop; ! 587: hNewThread = CreateThread(NULL,0, ! 588: (LPTHREAD_START_ROUTINE) ProcessFileCommonCode, ! 589: (LPVOID)lpTB,0,(LPDWORD)&iThread); ! 590: if (!hNewThread) ! 591: MessageBox(GetFocus(),"Failed","CreateThread",MB_OK); ! 592: aThreads[iArrayIndex] = hNewThread; ! 593: ! 594: ! 595: }; ! 596: /* We are now processing the last few threads. Clean up. */ ! 597: iEndLoop = min(iEndLoop,MAX_CONCURRENT_THREADS); ! 598: WaitForMultipleObjects(iEndLoop, aThreads,TRUE,INFINITE); ! 599: for (iLoop = 0; iLoop < iEndLoop ; iLoop++) ! 600: if (!CloseHandle(aThreads[iLoop])) ! 601: MessageBox(GetFocus(),"Can't delete thread!","",MB_OK); ! 602: wsprintf(tempFilBuf,"Total Hits: %d",iHitCount); ! 603: SetWindowText(hWndGlobal,tempFilBuf); ! 604: delete (MasterBlock); ! 605: SendMessage(hWndGlobal,WM_FREEAGAIN,0,0); ! 606: return(0); ! 607: } ! 608: ! 609: /********************************************************************/ ! 610: /* Following is the relevant stuff for the file manager extensions. */ ! 611: /********************************************************************/ ! 612: ! 613: LONG WINAPI FMExtensionProc(HWND hWndFileMan, WORD wMsg, LONG lParam) ! 614: { ! 615: static HMENU hSubMenu; ! 616: static UINT wDelta; ! 617: static HWND hWnd; ! 618: switch (wMsg) ! 619: { ! 620: ! 621: /* this message is sent to the extension proc to update its toolbar to ! 622: add custom buttons as accelarators for the extension menu. */ ! 623: ! 624: case FMEVENT_TOOLBARLOAD: ! 625: { ! 626: static EXT_BUTTON ExtButtons[1] = ! 627: { { IDM_STARTGREP-100, 0 , 0} }; /* This must correspond to the wMsg parameter passed to the extension proc */ ! 628: ! 629: #define lpTB ((LPFMS_TOOLBARLOAD) lParam) ! 630: ! 631: lpTB->dwSize = sizeof(FMS_TOOLBARLOAD); ! 632: lpTB->lpButtons = (LPEXT_BUTTON) &ExtButtons; ! 633: lpTB->cButtons = 1; ! 634: lpTB->cBitmaps = 1; ! 635: lpTB->idBitmap = IDM_STARTGREP; /* Must correspond to the bitmap identifier */ ! 636: return(TRUE); ! 637: }; ! 638: ! 639: /* this message is sent to the extension proc to associate a help string with ! 640: a menu item. */ ! 641: ! 642: case FMEVENT_HELPSTRING: ! 643: strcpy(((LPFMS_HELPSTRING)lParam)->szHelp,"Search for a string in multiple files"); ! 644: return (TRUE); ! 645: ! 646: case FMEVENT_LOAD: ! 647: if (!hOurselves) ! 648: return(NULL); ! 649: ! 650: hSubMenu = LoadMenu(hOurselves,"FileManMenu"); ! 651: wDelta = ((LPFMS_LOAD)lParam)->wMenuDelta; ! 652: ((LPFMS_LOAD)lParam)->dwSize= sizeof(FMS_LOAD); ! 653: strcpy(((LPFMS_LOAD)lParam)->szMenuName,"S&earch"); ! 654: ((LPFMS_LOAD)lParam)->hMenu = hSubMenu; ! 655: ! 656: ! 657: return (LONG) hSubMenu; ! 658: default: ! 659: switch (wMsg+100) ! 660: { ! 661: case IDM_DEFGREP: ! 662: DialogBox(hOurselves, ! 663: "StringDialog", ! 664: hWndFileMan, ! 665: (DLGPROC)StringProc); ! 666: break; ! 667: ! 668: case IDM_STARTGREP: ! 669: if (strlen(szGlobalSearchString) == 0) ! 670: if (!DialogBox(hOurselves, ! 671: "StringDialog", ! 672: hWndFileMan, ! 673: (DLGPROC)StringProc)) ! 674: break; ! 675: if (IsWindow(hWndGlobal)) ! 676: {MessageBox(GetFocus(),"No more than one window supported","Close hit window",MB_OK); ! 677: break; ! 678: }; ! 679: hWnd = CreateWindow( ! 680: WNDCLASSNAME, ! 681: "Windows NT File Search Extension", ! 682: WS_OVERLAPPEDWINDOW, ! 683: CW_USEDEFAULT, ! 684: CW_USEDEFAULT, ! 685: CW_USEDEFAULT, ! 686: CW_USEDEFAULT, ! 687: NULL, ! 688: NULL, ! 689: (HINSTANCE)GetCurrentProcess(), ! 690: NULL ! 691: ); ! 692: SendMessage(hWnd,WM_LAUNCH,0,(LONG)hWndFileMan); ! 693: ShowWindow(hWnd, SW_SHOWNORMAL); ! 694: UpdateWindow(hWnd); ! 695: break; ! 696: default: ! 697: break; ! 698: }; ! 699: return(0); ! 700: }; ! 701: } ! 702: ! 703:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.