ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

searchprogram.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004, 2005 Martin Fuchs
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017  */
00018 
00019 
00020  //
00021  // Explorer clone
00022  //
00023  // dialogs/searchprogram.cpp
00024  //
00025  // Explorer dialogs
00026  //
00027  // Martin Fuchs, 02.10.2003
00028  //
00029 
00030 
00031 #include <precomp.h>
00032 
00033 #include "../resource.h"
00034 
00035 #include "searchprogram.h"
00036 
00037 
00038 int CollectProgramsThread::Run()
00039 {
00040     try {
00041         collect_programs(SpecialFolderPath(CSIDL_COMMON_PROGRAMS, _hwnd));
00042     } catch(COMException&) {
00043     }
00044 
00045     if (_alive)
00046         try {
00047             collect_programs(SpecialFolderPath(CSIDL_PROGRAMS, _hwnd));
00048         } catch(COMException&) {
00049         }
00050 
00051     if (_alive)
00052         _cache_valid = true;
00053 
00054     return 0;
00055 }
00056 
00057 void CollectProgramsThread::collect_programs(const ShellPath& path)
00058 {
00059     ShellDirectory* dir = new ShellDirectory(GetDesktopFolder(), path, 0);
00060     _dirs.push(dir);
00061 
00062     dir->smart_scan(SORT_NONE);
00063 
00064     for(Entry*entry=dir->_down; _alive && entry; entry=entry->_next) {
00065         if (entry->_shell_attribs & SFGAO_HIDDEN)
00066             continue;
00067 
00068         if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00069             collect_programs(entry->create_absolute_pidl());
00070         else if (entry->_shell_attribs & SFGAO_LINK)
00071             if (_alive)
00072                 _callback(entry, _para);
00073     }
00074 }
00075 
00076 void CollectProgramsThread::free_dirs()
00077 {
00078     while(!_dirs.empty()) {
00079         ShellDirectory* dir = _dirs.top();
00080         dir->free_subentries();
00081         _dirs.pop();
00082     }
00083 }
00084 
00085 
00086 #ifdef _MSC_VER
00087 #pragma warning(disable: 4355)
00088 #endif
00089 
00090 FindProgramDlg::FindProgramDlg(HWND hwnd)
00091  :  super(hwnd),
00092     _list_ctrl(GetDlgItem(hwnd, IDC_PROGRAMS_FOUND)),
00093     _thread(collect_programs_callback, hwnd, this),
00094     _sort(_list_ctrl, CompareFunc/*, (LPARAM)this*/)
00095 {
00096     TCHAR szTemp[256];
00097     const size_t nChars = sizeof(szTemp)/sizeof(*szTemp);
00098     SetWindowIcon(hwnd, IDI_SEARCH);
00099 
00100     _resize_mgr.Add(IDC_FILTER,         RESIZE_X);
00101     _resize_mgr.Add(IDC_CHECK_ENTRIES,  MOVE_X);
00102     _resize_mgr.Add(IDC_PROGRAMS_FOUND, RESIZE);
00103 
00104     _resize_mgr.Resize(+520, +300);
00105 
00106     _haccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_SEARCH_PROGRAM));
00107 
00108     (void)ListView_SetImageList(_list_ctrl, g_Globals._icon_cache.get_sys_imagelist(), LVSIL_SMALL);
00109 
00110     LV_COLUMN column = {LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 250};
00111 
00112     LoadString(g_Globals._hInstance, IDS_NAMECOLUMN, szTemp, nChars);
00113     column.pszText = szTemp;
00114     ListView_InsertColumn(_list_ctrl, 0, &column);
00115 
00116     column.cx = 300;
00117     LoadString(g_Globals._hInstance, IDS_PATHCOLUMN, szTemp, nChars);
00118     column.pszText = szTemp;
00119     ListView_InsertColumn(_list_ctrl, 1, &column);
00120 
00121     column.cx = 400;
00122     LoadString(g_Globals._hInstance, IDS_MENUCOLUMN, szTemp, nChars);
00123     column.pszText = szTemp;
00124     ListView_InsertColumn(_list_ctrl, 2, &column);
00125 
00126     ListView_SetExtendedListViewStyleEx(_list_ctrl, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
00127 
00128     _common_programs = SpecialFolderFSPath(CSIDL_COMMON_PROGRAMS, hwnd);
00129     if (!_common_programs.empty())
00130         _common_programs.append(_T("\\"));
00131 
00132     _user_programs = SpecialFolderFSPath(CSIDL_PROGRAMS, hwnd);
00133     if (!_user_programs.empty())
00134         _user_programs.append(_T("\\"));
00135 
00136     CenterWindow(hwnd);
00137 
00138     Refresh();
00139 
00140     register_pretranslate(hwnd);
00141 }
00142 
00143 FindProgramDlg::~FindProgramDlg()
00144 {
00145     _thread.Stop();
00146 
00147     unregister_pretranslate(_hwnd);
00148 }
00149 
00150 
00151 void FindProgramDlg::Refresh(bool delete_cache)
00152 {
00153     WaitCursor wait;
00154 
00155     _thread.Stop();
00156 
00157     TCHAR buffer[1024];
00158     GetWindowText(GetDlgItem(_hwnd, IDC_FILTER), buffer, COUNTOF(buffer));
00159     CharLower(buffer);
00160     _lwr_filter = buffer;
00161 
00162     HiddenWindow hide_listctrl(_list_ctrl);
00163 
00164     ListView_DeleteAllItems(_list_ctrl);
00165 
00166     if (delete_cache || !_thread._cache_valid) {
00167         _thread.free_dirs();
00168         _thread.Start();
00169     } else {
00170         for(FPDCache::const_iterator it=_cache.begin(); it!=_cache.end(); ++it)
00171             add_entry(*it);
00172     }
00173 }
00174 
00175 void FindProgramDlg::collect_programs_callback(Entry* entry, void* param)
00176 {
00177     FindProgramDlg* pThis = (FindProgramDlg*) param;
00178 
00179     IShellLink* pShellLink;
00180     HRESULT hr = entry->GetUIObjectOf(pThis->_hwnd, IID_IShellLink, (LPVOID*)&pShellLink);
00181 
00182     if (SUCCEEDED(hr)) {
00183         ShellLinkPtr shell_link(pShellLink);
00184 
00185         shell_link->Release();
00186 
00187         /*hr = pShellLink->Resolve(pThis->_hwnd, SLR_NO_UI);
00188         if (SUCCEEDED(hr))*/ {
00189             WIN32_FIND_DATA wfd;
00190             TCHAR path[MAX_PATH];
00191 
00192             hr = pShellLink->GetPath(path, COUNTOF(path)-1, &wfd, SLGP_UNCPRIORITY);
00193 
00194             if (SUCCEEDED(hr)) {
00195                 TCHAR entry_path[MAX_PATH];
00196 
00197                 entry->get_path(entry_path, COUNTOF(entry_path));
00198 
00199                 String menu_path;
00200 
00201                 int len = pThis->_common_programs.size();
00202 
00203                 if (len && !_tcsnicmp(entry_path, pThis->_common_programs, len))
00204                     menu_path = ResString(IDS_ALL_USERS) + (String(entry_path)+len);
00205                 else if ((len=pThis->_user_programs.size()) && !_tcsnicmp(entry_path, pThis->_user_programs, len))
00206                     menu_path = String(entry_path)+len;
00207 
00208                  // store info in cache
00209                 FPDEntry new_entry;
00210 
00211                 new_entry._entry = entry;
00212                 new_entry._menu_path = menu_path;
00213                 new_entry._path = path;
00214                 new_entry._idxIcon = I_IMAGECALLBACK;
00215 
00216                 pThis->_cache.push_front(new_entry);
00217                 FPDEntry& cache_entry = pThis->_cache.front();
00218 
00219                 Lock lock(pThis->_thread._crit_sect);
00220 
00221                  // resolve deadlocks while executing Thread::Stop()
00222                 if (!pThis->_thread.is_alive())
00223                     return;
00224 
00225                 pThis->add_entry(cache_entry);
00226             }
00227         }
00228     }
00229 }
00230 
00231 void FindProgramDlg::add_entry(const FPDEntry& cache_entry)
00232 {
00233     String lwr_path = cache_entry._path;
00234     String lwr_name = cache_entry._entry->_display_name;
00235 
00236     lwr_path.toLower();
00237     lwr_name.toLower();
00238 
00239     if (_lwr_filter.empty())
00240         if (_tcsstr(lwr_name, _T("uninstal")) || _tcsstr(lwr_name, _T("deinstal"))) // filter out deinstallation links
00241             return;
00242 
00243     if (!_tcsstr(lwr_path, _lwr_filter) && !_tcsstr(lwr_name, _lwr_filter))
00244         return;
00245 
00246     LV_ITEM item = {LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM, INT_MAX};
00247 
00248     item.pszText = cache_entry._entry->_display_name;
00249     item.iImage = cache_entry._idxIcon;
00250     item.lParam = (LPARAM) &cache_entry;
00251     item.iItem = ListView_InsertItem(_list_ctrl, &item);    // We could use the information in _sort to enable manual sorting while populating the list.
00252 
00253     item.mask = LVIF_TEXT;
00254 
00255     item.iSubItem = 1;
00256     item.pszText = (LPTSTR)(LPCTSTR)cache_entry._path;
00257     ListView_SetItem(_list_ctrl, &item);
00258 
00259     item.iSubItem = 2;
00260     item.pszText = (LPTSTR)(LPCTSTR)cache_entry._menu_path;
00261     ListView_SetItem(_list_ctrl, &item);
00262 }
00263 
00264 LRESULT FindProgramDlg::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00265 {
00266     switch(nmsg) {
00267       case WM_CLOSE:
00268         (void)ListView_SetImageList(_list_ctrl, 0, LVSIL_SMALL);    // detach system image list
00269         goto def;
00270 
00271       case PM_TRANSLATE_MSG: {
00272         MSG* pmsg = (MSG*) lparam;
00273 
00274         if (TranslateAccelerator(_hwnd, _haccel, pmsg))
00275             return TRUE;
00276 
00277         return FALSE;}
00278 
00279       default: def:
00280         return super::WndProc(nmsg, wparam, lparam);
00281     }
00282 
00283     return 0;
00284 }
00285 
00286 int FindProgramDlg::Command(int id, int code)
00287 {
00288     if (code == BN_CLICKED) {
00289         switch(id) {
00290           case ID_REFRESH:
00291             Refresh(true);
00292             break;
00293 
00294           case IDOK:
00295             LaunchSelected();
00296             break;
00297 
00298           case IDC_CHECK_ENTRIES:
00299             CheckEntries();
00300             break;
00301 
00302           default:
00303             return super::Command(id, code);
00304         }
00305 
00306         return 0;
00307     }
00308     else if (code == EN_CHANGE) {
00309         switch(id) {
00310           case IDC_FILTER:
00311             Refresh();
00312             break;
00313         }
00314 
00315         return 0;
00316     }
00317 
00318     return 1;
00319 }
00320 
00321 void FindProgramDlg::LaunchSelected()
00322 {
00323     Lock lock(_thread._crit_sect);
00324 
00325     int count = ListView_GetSelectedCount(_list_ctrl);
00326 
00327     if (count > 1)
00328         if (MessageBox(_hwnd, ResString(IDS_LAUNCH_MANY_PROGRAMS), ResString(IDS_TITLE), MB_OKCANCEL) != IDOK)
00329             return;
00330 
00331     for(int idx=-1; (idx=ListView_GetNextItem(_list_ctrl, idx, LVNI_SELECTED))!=-1; ) {
00332         LPARAM lparam = ListView_GetItemData(_list_ctrl, idx);
00333 
00334         if (lparam) {
00335             FPDEntry& cache_entry = *(FPDEntry*)lparam;
00336             cache_entry._entry->launch_entry(_hwnd);
00337         }
00338     }
00339 }
00340 
00341 int FindProgramDlg::Notify(int id, NMHDR* pnmh)
00342 {
00343     switch(pnmh->code) {
00344       case LVN_GETDISPINFO: {
00345         LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pnmh;
00346 
00347         if (pnmh->hwndFrom == _list_ctrl) {
00348             if (pDispInfo->item.mask & LVIF_IMAGE) {
00349                 FPDEntry& cache_entry = *(FPDEntry*)pDispInfo->item.lParam;
00350                 Entry* entry = cache_entry._entry;
00351 
00352                 if (entry->_icon_id == ICID_UNKNOWN)
00353                     entry->_icon_id = entry->extract_icon(ICF_SYSCACHE);
00354 
00355                 pDispInfo->item.iImage = g_Globals._icon_cache.get_icon(entry->_icon_id).get_sysiml_idx();
00356                 pDispInfo->item.mask |= LVIF_DI_SETITEM;
00357 
00358                 return 1;
00359             }
00360         }}
00361         break;
00362 
00363       case NM_DBLCLK:
00364         if (pnmh->hwndFrom == _list_ctrl)
00365             LaunchSelected();
00366         /*{
00367             Lock lock(_thread._crit_sect);
00368 
00369             LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmh;
00370             LPARAM lparam = ListView_GetItemData(pnmh->hwndFrom, pnmv->iItem);
00371 
00372             if (lparam) {
00373                 FPDEntry& cache_entry = *(FPDEntry*)lparam;
00374                 cache_entry._entry->launch_entry(_hwnd);
00375             }
00376         }*/
00377         break;
00378 
00379       case HDN_ITEMCLICK: {
00380         WaitCursor wait;
00381         NMHEADER* phdr = (NMHEADER*)pnmh;
00382 
00383         if (GetParent(pnmh->hwndFrom) == _list_ctrl) {
00384             if (_thread._cache_valid) { // disable manual sorting while populating the list
00385                 _sort.toggle_sort(phdr->iItem);
00386                 _sort.sort();
00387             }
00388         }
00389         break;}
00390     }
00391 
00392     return 0;
00393 }
00394 
00395 int CALLBACK FindProgramDlg::CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort)
00396 {
00397     ListSort* sort = (ListSort*)lparamSort;
00398 
00399     FPDEntry& a = *(FPDEntry*)lparam1;
00400     FPDEntry& b = *(FPDEntry*)lparam2;
00401 
00402     int cmp = 0;
00403 
00404     switch(sort->_sort_crit) {
00405       case 0:
00406         cmp = _tcsicoll(a._entry->_display_name, b._entry->_display_name);
00407         break;
00408 
00409       case 1:
00410         cmp = _tcsicoll(a._path, b._path);
00411         break;
00412 
00413       case 2:
00414         cmp = _tcsicoll(a._menu_path, b._menu_path);
00415     }
00416 
00417     return sort->_direction? -cmp: cmp;
00418 }
00419 
00420 void FindProgramDlg::CheckEntries()
00421 {
00423 }

Generated on Sat May 26 2012 04:17:27 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.