/****************************************************************************/ /* */ /* WFSEARCH.C - */ /* */ /* File System Search Routines */ /* */ /****************************************************************************/ #include "winfile.h" #include "lfn.h" INT maxExt; INT iDirsRead; DWORD LastUpdateTime; WORD APIENTRY StackAvail(VOID); INT FillSearchLB(HWND hwndLB, LPSTR szSearchFileSpec, BOOL bSubDirOnly); INT SearchList(HWND hwndLB, LPSTR szPath, LPSTR szFileSpec, BOOL bRecurse, LPHANDLE lphMem, INT iFileCount); LPSTR SearchGetSelection(HWND hwndLB, BOOL bMostRecent, BOOL *pfDir); /*--------------------------------------------------------------------------*/ /* */ /* SearchList() - */ /* */ /* This is a recursive routine. It returns the number of files found. */ // szPath OEM // szFileSpec OEM /* */ /*--------------------------------------------------------------------------*/ #define DTA_GRANULARITY 20 INT SearchList( HWND hwndLB, LPSTR szPath, LPSTR szFileSpec, BOOL bRecurse, LPHANDLE lphMem, INT iFileCount ) { INT iRetVal; INT cxExt; BOOL bFound; LPSTR pszNewPath; LPSTR pszNextFile; LFNDTA lfndta; LPDTASEARCH lpdtasch; HDC hdc; HANDLE hOld; HANDLE hMem, hMemT; DWORD TimeNow; STKCHK(); hMem = *lphMem; /* Just return 0 files so parent dirs will still be searched */ if (StackAvail() < 1024) return(iFileCount); TimeNow = GetTickCount(); if (TimeNow > LastUpdateTime+1000) { LastUpdateTime = TimeNow; if (LoadString(hAppInstance, IDS_DIRSREAD, szMessage, sizeof(szMessage))) wsprintf(szStatusTree, szMessage, iDirsRead); InvalidateRect(hwndFrame, NULL, FALSE); UpdateWindow(hwndFrame); } iDirsRead++; if (!hMem) { hMem = LocalAlloc(LPTR, (DWORD)DTA_GRANULARITY * sizeof(DTASEARCH)); if (!hMem) return -1; *lphMem = hMem; } lpdtasch = (LPDTASEARCH)LocalLock(hMem); // allocate the buffer for this level pszNewPath = (LPSTR)LocalAlloc(LPTR, lstrlen(szPath) + MAXFILENAMELEN + 2); if (!pszNewPath) return -1; lstrcpy(pszNewPath, szPath); AddBackslash(pszNewPath); pszNextFile = pszNewPath + lstrlen(pszNewPath); lstrcpy(pszNextFile, szFileSpec); bFound = WFFindFirst(&lfndta, pszNewPath, ATTR_ALL); hdc = GetDC(hwndLB); hOld = SelectObject(hdc, hFont); while (bFound) { // alow escape to exit if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) { bRecurse = FALSE; iFileCount = -1; break; } // Make sure this is not a "." or ".." directory if (lfndta.fd.cFileName[0] != '.') { BOOL bLFN; lstrcpy(pszNextFile, lfndta.fd.cFileName); OemToAnsi(pszNewPath, szMessage); bLFN = IsLFN(lfndta.fd.cFileName); iRetVal = (INT)SendMessage(hwndLB, LB_ADDSTRING, 0, (LPARAM)szMessage); MGetTextExtent(hdc, szMessage, lstrlen(szMessage), &cxExt, NULL); maxExt = max(maxExt, cxExt); if (iRetVal >= 0) { if (iFileCount && ((iFileCount % DTA_GRANULARITY) == 0)) { LocalUnlock(hMem); if (!(hMemT = LocalReAlloc(hMem, (DWORD)((iFileCount + DTA_GRANULARITY) * sizeof(DTASEARCH)), LMEM_MOVEABLE))) { LocalLock(hMem); bRecurse = FALSE; // simulate an abort iFileCount = -1; break; } else { hMem = hMemT; *lphMem = hMemT; } lpdtasch = (LPDTASEARCH)LocalLock(hMem); } lpdtasch[iFileCount] = *((LPDTASEARCH)(&lfndta.fd)); if (bLFN) lpdtasch[iFileCount].sch_dwAttrs |= ATTR_LFN; SendMessage(hwndLB, LB_SETITEMDATA, iRetVal, (LONG)iFileCount); iFileCount++; } } /* Search for more files in the current directory */ bFound = WFFindNext(&lfndta); } WFFindClose(&lfndta); if (hOld) SelectObject(hdc, hOld); ReleaseDC(hwndLB, hdc); LocalUnlock(hMem); SetWindowLongPtr(GetParent(hwndLB), GWLP_HDTASEARCH, (LONG_PTR)hMem); if (!bRecurse) goto SearchEnd; /* Now see if there are any subdirectories here */ lstrcpy(pszNextFile, szStarDotStar); bFound = WFFindFirst(&lfndta, pszNewPath, ATTR_DIR | ATTR_HS); while (bFound) { // alow escape to exit if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) { bRecurse = FALSE; iFileCount = -1; break; } /* Make sure this is not a "." or ".." directory. */ if ((lfndta.fd.cFileName[0] != '.') && (lfndta.fd.dwFileAttributes & ATTR_DIR)) { /* Yes, search and add files in this directory */ lstrcpy(pszNextFile, lfndta.fd.cFileName); /* Add all files in this subdirectory. */ if ((iRetVal = SearchList(hwndLB, pszNewPath, szFileSpec, bRecurse, lphMem, iFileCount)) < 0) { iFileCount = iRetVal; break; } iFileCount = iRetVal; } bFound = WFFindNext(&lfndta); } WFFindClose(&lfndta); SearchEnd: LocalFree((HANDLE)pszNewPath); return iFileCount; } VOID FixUpFileSpec( LPSTR szFileSpec ) { CHAR szTemp[MAXPATHLEN+1]; register LPSTR p; if (*szFileSpec == '.') { lstrcpy(szTemp, "*"); lstrcat(szTemp, szFileSpec); lstrcpy(szFileSpec, szTemp); } /* HACK: If there isn't a dot and the last char is a *, append ".*" */ p = szFileSpec; while ((*p) && (*p != '.')) p = AnsiNext(p); if ((!*p) && (p != szFileSpec)) { p = AnsiPrev(szFileSpec, p); if (*p == '*') lstrcat(p, ".*"); } } /*--------------------------------------------------------------------------*/ /* */ /* FillSearchLB() - */ /* */ /*--------------------------------------------------------------------------*/ /* This parses the given string for Drive, PathName, FileSpecs and * calls SearchList() with proper parameters; * * hwndLB : List box where files are to be displayed; * szSearchFileSpec : ANSI path to search * bSubDirOnly : TRUE, if only subdirectories are to be searched; */ INT FillSearchLB( HWND hwndLB, LPSTR szSearchFileSpec, BOOL bRecurse ) { INT iRet; HCURSOR hCursor; CHAR szFileSpec[MAXPATHLEN+1]; CHAR szPathName[MAXPATHLEN+1]; HANDLE hMemIn = NULL; FixAnsiPathForDos(szSearchFileSpec); /* Get the file specification part of the string. */ lstrcpy(szFileSpec, szSearchFileSpec); lstrcpy(szPathName, szSearchFileSpec); StripPath(szFileSpec); StripFilespec(szPathName); FixUpFileSpec(szFileSpec); hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); ShowCursor(TRUE); maxExt = 0; iDirsRead = 1; LastUpdateTime = 0; iRet = SearchList(hwndLB, szPathName, szFileSpec, bRecurse, &hMemIn, 0); ShowCursor(FALSE); SetCursor(hCursor); SendMessage(hwndLB, LB_SETSEL, TRUE, 0L); return(iRet); } /*--------------------------------------------------------------------------*/ /* */ /* SearchGetSelection() - */ /* */ /*--------------------------------------------------------------------------*/ /* Returns a string containing the names of the selected * files seperated by spaces. If bMostRecent is TRUE, it only returns the * most recently selected file. * * The string is returned and a *pfDir is set indicating if it points * to a directory. * * NOTE: The caller must free the returned pointer! */ LPSTR SearchGetSelection( HWND hwndLB, BOOL bMostRecent, BOOL *pfDir ) { register LPSTR p; LPSTR pT; register WORD i; WORD iMac; WORD cch = 1; BOOL bDir; HANDLE hMem; LPDTASEARCH lpdtasch; CHAR szTemp[MAXPATHLEN]; BOOL bLFNTest; if (bLFNTest = (bMostRecent == 2)) { bMostRecent = FALSE; } else { p = (LPSTR)LocalAlloc(LPTR, 1); if (!p) return NULL; } if (bMostRecent == 3) bMostRecent = 0; bDir = TRUE; iMac = (WORD)SendMessage(hwndLB, LB_GETCOUNT, 0, 0L); hMem = (HANDLE)GetWindowLongPtr(GetParent(hwndLB), GWLP_HDTASEARCH); lpdtasch = (LPDTASEARCH)LocalLock(hMem); for (i=0; i < iMac; i++) { if (!(BOOL)SendMessage(hwndLB, LB_GETSEL, i, 0L)) continue; cch += (WORD)SendMessage(hwndLB, LB_GETTEXT, i, (LPARAM)szTemp); cch++; if (bLFNTest) { if (IsLFN(szTemp)) { if (pfDir) *pfDir = TRUE; return NULL; } } else { pT = (LPSTR)LocalReAlloc((HANDLE)p, cch, LMEM_MOVEABLE | LMEM_ZEROINIT); if (!pT) goto SGSExit; p = pT; lstrcat(p, szTemp); bDir = lpdtasch[(INT)SendMessage(hwndLB, LB_GETITEMDATA, i, 0L)].sch_dwAttrs & ATTR_DIR; if (bMostRecent) break; lstrcat(p, szBlank); } } SGSExit: LocalUnlock(hMem); if (bLFNTest) { if (pfDir) *pfDir = FALSE; return NULL; } if (pfDir) *pfDir = bDir; return(p); } VOID CreateLine( WORD wLineFormat, LPSTR szFile, LPDTASEARCH lpdtasch, LPSTR szBuffer ) { LPSTR pch; BYTE chAttribute; pch = szBuffer; chAttribute = (BYTE)lpdtasch->sch_dwAttrs; /* Copy the file name. */ lstrcpy(pch, szFile); pch += lstrlen(pch); *pch = TEXT('\0'); /* Should we show the size? */ if (wLineFormat & VIEW_SIZE) { *pch++ = TABCHAR; if (!(chAttribute & ATTR_DIR)) pch += PutSize(lpdtasch->sch_nFileSizeLow, pch); } /* Should we show the date? */ if (wLineFormat & VIEW_DATE) { *pch++ = TABCHAR; pch += PutDate(&lpdtasch->sch_ftLastWriteTime, pch); } /* Should we show the time? */ if (wLineFormat & VIEW_TIME) { *pch++ = TABCHAR; pch += PutTime(&lpdtasch->sch_ftLastWriteTime, pch); } /* Should we show the attributes? */ if (wLineFormat & VIEW_FLAGS) { *pch++ = TABCHAR; pch += PutAttributes((WORD)chAttribute, pch); } } // the window text looks like "Search Window: C:\FOO\BAR\*.*" VOID GetSearchPath( HWND hWnd, LPSTR pszPath ) { LPSTR p; CHAR szTemp[MAXPATHLEN+32]; // the search window doesn't have a current directory GetWindowText(hWnd, szTemp, sizeof(szTemp)); // the window text looks like "Search Window: C:\FOO\BAR\*.*" p = szTemp; while (*p && *p != ':') // find the : p = AnsiNext(p); p += 2; // skip the ": " lstrcpy(pszPath, p); } /*--------------------------------------------------------------------------*/ /* */ /* UpdateSearchStatus() - */ /* */ /*--------------------------------------------------------------------------*/ VOID UpdateSearchStatus( HWND hwndLB ) { INT nCount; nCount = (INT)SendMessage(hwndLB, LB_GETCOUNT, 0, 0L); if (LoadString(hAppInstance, IDS_SEARCHMSG, szMessage, sizeof(szMessage))) wsprintf(szStatusTree, szMessage, nCount); szStatusDir[0] = '\0'; InvalidateRect(hwndFrame, NULL, FALSE); } /*--------------------------------------------------------------------------*/ /* */ /* SearchWndProc() - */ /* */ /*--------------------------------------------------------------------------*/ INT_PTR APIENTRY SearchWndProc( register HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) { INT iRet; INT iSel; HWND hwndLB; CHAR szTemp[MAXPATHLEN + 32]; CHAR szPath[MAXPATHLEN]; STKCHK(); hwndLB = GetDlgItem(hWnd, IDCW_LISTBOX); switch (wMsg) { case FS_GETDRIVE: MSG("SearchWndProc", "FS_GETDRIVE"); // Returns the letter of the corresponding directory SendMessage(hWnd, FS_GETDIRECTORY, sizeof(szPath), (LPARAM)szPath); return szPath[0]; // first character case FS_GETDIRECTORY: MSG("SearchWndProc", "FS_GETDIRECTORY"); GetSearchPath(hWnd, szPath); StripFilespec(szPath); // remove the filespec AddBackslash(szPath); // to be the same as DirWndProc lstrcpy((LPSTR)lParam, szPath); break; case FS_GETFILESPEC: MSG("SearchWndProc", "FS_GETFILESPEC"); // the search window doesn't have a current directory GetSearchPath(hWnd, szPath); StripPath(szPath); // remove the path (leave the filespec) lstrcpy((LPSTR)lParam, szPath); break; case FS_SETSELECTION: MSG("SearchWndProc", "FS_SETSELECTION"); // wParam is the select(TRUE)/unselect(FALSE) param // lParam is the filespec to match against SendMessage(hwndLB, WM_SETREDRAW, FALSE, 0L); DSSetSelection(hwndLB, wParam ? TRUE : FALSE, (LPSTR)lParam, TRUE); SendMessage(hwndLB, WM_SETREDRAW, TRUE, 0L); InvalidateRect(hwndLB, NULL, TRUE); break; case FS_GETSELECTION: MSG("SearchWndProc", "FS_GETSELECTION"); return (INT_PTR)SearchGetSelection(hwndLB, wParam ? TRUE : FALSE, (BOOL *)lParam); break; case WM_MDIACTIVATE: if (wParam) { UpdateSearchStatus(hwndLB); // if we are dirty, ask if we should update if (GetWindowLong(hWnd, GWL_FSCFLAG)) PostMessage(hWnd, FS_CHANGEDISPLAY, CD_SEARCHUPDATE, 0L); } break; case WM_FILESYSCHANGE: SetWindowLong(hWnd, GWL_FSCFLAG, TRUE); // I need updating // if the search window is not active or FSCs are disabled // don't prompt now, wait till we get the end FSC or are // activated (above in WM_ACTIVATE) if (cDisableFSC || (hWnd != (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L)) && (GetActiveWindow() != hwndFrame)) break; PostMessage(hWnd, FS_CHANGEDISPLAY, CD_SEARCHUPDATE, 0L); break; case FS_CHANGEDISPLAY: MSG("SearchWndProc", "FS_CHANGEDISPLAY"); SetWindowLong(hWnd, GWL_FSCFLAG, FALSE); // I am clean if (wParam == CD_SEARCHUPDATE) { LoadString(hAppInstance, IDS_SEARCHTITLE, szTitle, sizeof(szTitle)); LoadString(hAppInstance, IDS_SEARCHREFRESH, szMessage, sizeof(szMessage)); if (MessageBox(hWnd, szMessage, szTitle, MB_YESNO | MB_ICONQUESTION) != IDYES) break; } // is this a refresh? if (!lParam) { GetSearchPath(hWnd, szPath); } else { lstrcpy(szPath, (LPSTR)lParam); // explicit re-search } LoadString(hAppInstance, IDS_SEARCHTITLE, szMessage, 32); lstrcat(szMessage, szPath); SetWindowText(hWnd, szMessage); SendMessage(hwndLB, WM_SETREDRAW, FALSE, 0L); SendMessage(hwndLB, LB_RESETCONTENT, 0, 0L); iRet = FillSearchLB(hwndLB, szPath, bSearchSubs); FixTabsAndThings(hwndLB,(WORD *)GetWindowLongPtr(hWnd, GWLP_TABARRAYSEARCH), maxExt + dxText,wNewView); SendMessage(hwndLB, WM_SETREDRAW, TRUE, 0L); InvalidateRect(hwndLB, NULL, TRUE); if (iRet == 0) { LoadString(hAppInstance, IDS_SEARCHTITLE, szTitle, sizeof(szTitle)); LoadString(hAppInstance, IDS_SEARCHNOMATCHES, szMessage, sizeof(szMessage)); MessageBox(hwndFrame, szMessage, szTitle, MB_OK | MB_ICONINFORMATION); ShowWindow(hWnd, SW_HIDE); PostMessage(hWnd, WM_CLOSE, 0, 0L); return FALSE; } else { UpdateSearchStatus(hwndLB); } if (GetFocus() != hwndLB) return(iRet); /*** FALL THRU ***/ case WM_SETFOCUS: MSG("SearchWndProc", "WM_SETFOCUS"); SetFocus(hwndLB); return (WORD)SendMessage(hwndLB, LB_GETCOUNT, 0, 0L); case WM_CLOSE: MSG("SearchWndProc", "WM_CLOSE"); hwndSearch = NULL; goto DefChildProc; case WM_COMMAND: /* Was this a double-click? */ if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_DBLCLK) SendMessage(hwndFrame, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_OPEN, 0, 0)); else if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE) { INT i; for (i = 0; i < iNumExtensions; i++) { (extensions[i].ExtProc)(hwndFrame, FMEVENT_SELCHANGE, 0L); } } break; case WM_DESTROY: MSG("SearchWndProc", "WM_DESTROY"); { HANDLE hMem; if (hMem = (HANDLE)GetWindowLongPtr(hWnd, GWLP_HDTASEARCH)) LocalFree(hMem); if (hMem = (HANDLE)GetWindowLongPtr(hWnd, GWLP_TABARRAYSEARCH)) LocalFree(hMem); } break; case WM_CREATE: TRACE(BF_WM_CREATE, "SearchWndProc - WM_CREATE"); { // globals used: // szSearch path to start search at // bSearchSubs tells us to do a recursive search RECT rc; WORD *pwTabs; GetClientRect(hWnd, &rc); hwndLB = CreateWindowEx(0, szListbox, NULL, WS_CHILD | WS_BORDER | LBS_SORT | LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL | LBS_NOINTEGRALHEIGHT | LBS_WANTKEYBOARDINPUT | LBS_HASSTRINGS | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, -1, -1, rc.right+2, rc.bottom+2, hWnd, (HMENU)IDCW_LISTBOX, hAppInstance, NULL); if (!hwndLB) return -1L; if ((pwTabs = (WORD *)LocalAlloc(LPTR,sizeof(WORD) * 4)) == NULL) return -1L; hwndSearch = hWnd; SetWindowLong(hWnd, GWL_TYPE, TYPE_SEARCH); SetWindowLong(hWnd, GWL_VIEW, wNewView); SetWindowLong(hWnd, GWL_SORT, IDD_NAME); SetWindowLong(hWnd, GWL_ATTRIBS,ATTR_DEFAULT); SetWindowLong(hWnd, GWL_FSCFLAG, FALSE); SetWindowLongPtr(hWnd, GWLP_HDTASEARCH, 0); SetWindowLongPtr(hWnd, GWLP_TABARRAYSEARCH, (LONG_PTR)pwTabs); SetWindowLongPtr(hWnd, GWLP_LASTFOCUSSEARCH, (LONG_PTR)hwndLB); // Fill the listbox if (!FillSearchLB(hwndLB, szSearch, bSearchSubs)) { LoadString(hAppInstance, IDS_SEARCHTITLE, szTitle, sizeof(szTitle)); LoadString(hAppInstance, IDS_SEARCHNOMATCHES, szMessage, sizeof(szMessage)); MessageBox(hwndFrame, szMessage, szTitle, MB_OK | MB_ICONINFORMATION); hwndSearch = NULL; return -1L; } else { FixTabsAndThings(hwndLB,pwTabs, maxExt + dxText,wNewView); SendMessage(hwndLB, WM_SETFONT, (WPARAM)hFont, 0L); ShowWindow(hwndSearch, SW_SHOWNORMAL); } break; } case WM_DRAGLOOP: MSG("SearchWndProc", "WM_DRAGLOOP"); /* WM_DRAGLOOP is sent to the source window as the object is moved. * * wParam: TRUE if the object is currently over a droppable sink * lParam: LPDROPSTRUCT */ /* DRAGLOOP is used to turn the source bitmaps on/off as we drag. */ DSDragLoop(hwndLB, wParam, (LPDROPSTRUCT)lParam, TRUE); break; case WM_DRAGSELECT: MSG("SearchWndProc", "WM_DRAGSELECT"); /* WM_DRAGSELECT is sent to a sink whenever an new object is dragged * inside of it. * * wParam: TRUE if the sink is being entered, FALSE if it's being * exited. * lParam: LPDROPSTRUCT */ /* DRAGSELECT is used to turn our selection rectangle on or off. */ #define lpds ((LPDROPSTRUCT)lParam) iSelHilite = LOWORD(lpds->dwControlData); DSRectItem(hwndLB, iSelHilite, (BOOL)wParam, TRUE); break; case WM_DRAGMOVE: MSG("SearchWndProc", "WM_DRAGMOVE"); /* WM_DRAGMOVE is sent to a sink as the object is being dragged * within it. * * wParam: Unused * lParam: LPDROPSTRUCT */ /* DRAGMOVE is used to move our selection rectangle among sub-items. */ #define lpds ((LPDROPSTRUCT)lParam) /* Get the subitem we are over. */ iSel = LOWORD(lpds->dwControlData); /* Is it a new one? */ if (iSel == iSelHilite) break; /* Yup, un-select the old item. */ DSRectItem(hwndLB, iSelHilite, FALSE, TRUE); /* Select the new one. */ iSelHilite = iSel; DSRectItem(hwndLB, iSel, TRUE, TRUE); break; case WM_DRAWITEM: MSG("SearchWndProc", "WM_DRAWITEM"); { LPDRAWITEMSTRUCT lpLBItem; HANDLE hMem; LPDTASEARCH lpdtasch; lpLBItem = (LPDRAWITEMSTRUCT)lParam; iSel = lpLBItem->itemID; if (iSel < 0) break; SendMessage(hwndLB, LB_GETTEXT, iSel, (LPARAM)szPath); hMem = (HANDLE)GetWindowLongPtr(hWnd, GWLP_HDTASEARCH); lpdtasch = (LPDTASEARCH)LocalLock(hMem); iSel = (INT)SendMessage(hwndLB, LB_GETITEMDATA, iSel, 0L); CreateLine((WORD)GetWindowLong(hWnd, GWL_VIEW), szPath, &(lpdtasch[iSel]), szTemp); DrawItem(lpLBItem, szTemp, lpdtasch[iSel].sch_dwAttrs, TRUE, (WORD *)GetWindowLongPtr(hWnd,GWLP_TABARRAYSEARCH)); LocalUnlock(hMem); break; } case WM_DROPOBJECT: MSG("SearchWndProc", "WM_DROPOBJECT"); { LPSTR pFrom; WORD ret; WORD iSelSink; HANDLE hMem; LPDTASEARCH lpdtasch; DWORD attrib; /* WM_DROPOBJECT is sent to a sink when the user releases an * acceptable object over it * * wParam: TRUE if over the non-client area, FALSE if over the * client area. * lParam: LPDROPSTRUCT */ #define lpds ((LPDROPSTRUCT)lParam) iSelSink = LOWORD(lpds->dwControlData); /* Are we dropping onto ourselves? (i.e. a selected item in the * source listbox OR an unused area of the source listbox) If * so, don't do anything. */ if (hWnd == lpds->hwndSource) { if ((iSelSink == 0xFFFF) || (SendMessage(hwndLB, LB_GETSEL, iSelSink, 0L))) return TRUE; } /* Are we dropping on a unused portion of the listbox? */ if (iSelSink == 0xFFFF) return TRUE; /* Get the sink's filename. */ SendMessage(hwndLB, LB_GETTEXT, iSelSink, (LPARAM)szPath); hMem = (HANDLE)GetWindowLongPtr(hWnd, GWLP_HDTASEARCH); lpdtasch = (LPDTASEARCH)LocalLock(hMem); attrib = lpdtasch[(INT)SendMessage(hwndLB, LB_GETITEMDATA, iSelSink, 0L)].sch_dwAttrs; LocalUnlock(hMem); /* Are we dropping on a subdirectory? */ if (attrib & ATTR_DIR) goto DirMoveCopy; /* Are we not dropping on a Program file? */ if (!IsProgramFile(szPath)) return TRUE; if (lpds->wFmt == DOF_DIRECTORY) { goto DODone; } /* We're dropping a file onto a program. * Exec the program using the source file as the parameter. */ /* Should we confirm it first? */ if (bConfirmMouse) { LoadString(hAppInstance, IDS_MOUSECONFIRM, szTitle, MAXTITLELEN); LoadString(hAppInstance, IDS_EXECMOUSECONFIRM, szTemp, sizeof(szTemp)); wsprintf(szMessage, szTemp, (LPSTR)szPath, (LPSTR)(((LPDRAGOBJECTDATA)(lpds->dwData))->pch)); if (MessageBox(hwndFrame, szMessage, szTitle, MB_YESNO | MB_ICONEXCLAMATION) == IDNO) goto DODone; } /* If we dragged from a Dir Window, add path information. */ if (lpds->hwndSource == hWnd) szTemp[0] = TEXT('\0'); else SendMessage(lpds->hwndSource, FS_GETDIRECTORY, sizeof(szTemp), (LPARAM)szTemp); lstrcat(szTemp, (LPSTR)(((LPDRAGOBJECTDATA)(lpds->dwData))->pch)); // put a "." extension on if none found if (*GetExtension(szTemp) == 0) lstrcat(szTemp, "."); FixAnsiPathForDos(szTemp); FixAnsiPathForDos(szPath); ret = ExecProgram(szPath,szTemp,NULL,FALSE); if (ret) MyMessageBox(hwndFrame, IDS_EXECERRTITLE, ret, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL); DODone: DSRectItem(hwndLB, iSelHilite, FALSE, TRUE); return TRUE; DirMoveCopy: pFrom = (LPSTR)(((LPDRAGOBJECTDATA)(lpds->dwData))->pch); AddBackslash(szPath); // add filespec filter lstrcat(szPath, szStarDotStar); DMMoveCopyHelper(pFrom, szPath, fShowSourceBitmaps); DSRectItem(hwndLB, iSelHilite, FALSE, TRUE); return TRUE; } case WM_LBTRACKPOINT: MSG("SearchWndProc", "WM_LBTRACKPOINT"); return(DSTrackPoint(hWnd, hwndLB, wParam, lParam, TRUE)); case WM_MEASUREITEM: MSG("SearchWndProc", "WM_MEASUREITEM"); { #define pLBMItem ((LPMEASUREITEMSTRUCT)lParam) pLBMItem->itemHeight = dyFileName; break; } case WM_QUERYDROPOBJECT: MSG("SearchWndProc", "WM_QUERYDROPOBJECT"); /* Ensure that we are dropping on the client area of the listbox. */ #define lpds ((LPDROPSTRUCT)lParam) /* Ensure that we can accept the format. */ switch (lpds->wFmt) { case DOF_EXECUTABLE: case DOF_DIRECTORY: case DOF_DOCUMENT: case DOF_MULTIPLE: if (lpds->hwndSink == hWnd) lpds->dwControlData = -1L; return TRUE; } return FALSE; case WM_SIZE: MSG("SearchWndProc", "WM_SIZE"); if (wParam != SIZEICONIC) { MoveWindow(GetDlgItem(hWnd, IDCW_LISTBOX), -1, -1, LOWORD(lParam)+2, HIWORD(lParam)+2, TRUE); } /*** FALL THRU ***/ default: DefChildProc: DEFMSG("SearchWndProc", (WORD)wMsg); return(DefMDIChildProc(hWnd, wMsg, wParam, lParam)); } return(0L); }