+++ /dev/null
-/*
- * Copyright 2003, 2004, 2005 Martin Fuchs
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
- //
- // Explorer clone
- //
- // dialogs/searchprogram.cpp
- //
- // Explorer dialogs
- //
- // Martin Fuchs, 02.10.2003
- //
-
-
-#include <precomp.h>
-
-#include "searchprogram.h"
-
-
-int CollectProgramsThread::Run()
-{
- try {
- collect_programs(SpecialFolderPath(CSIDL_COMMON_PROGRAMS, _hwnd));
- } catch(COMException&) {
- }
-
- if (_alive)
- try {
- collect_programs(SpecialFolderPath(CSIDL_PROGRAMS, _hwnd));
- } catch(COMException&) {
- }
-
- if (_alive)
- _cache_valid = true;
-
- return 0;
-}
-
-void CollectProgramsThread::collect_programs(const ShellPath& path)
-{
- ShellDirectory* dir = new ShellDirectory(GetDesktopFolder(), path, 0);
- _dirs.push(dir);
-
- dir->smart_scan(SORT_NONE);
-
- for(Entry*entry=dir->_down; _alive && entry; entry=entry->_next) {
- if (entry->_shell_attribs & SFGAO_HIDDEN)
- continue;
-
- if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- collect_programs(entry->create_absolute_pidl());
- else if (entry->_shell_attribs & SFGAO_LINK)
- if (_alive)
- _callback(entry, _para);
- }
-}
-
-void CollectProgramsThread::free_dirs()
-{
- while(!_dirs.empty()) {
- ShellDirectory* dir = _dirs.top();
- dir->free_subentries();
- _dirs.pop();
- }
-}
-
-
-#ifdef _MSC_VER
-#pragma warning(disable: 4355)
-#endif
-
-FindProgramDlg::FindProgramDlg(HWND hwnd)
- : super(hwnd),
- _list_ctrl(GetDlgItem(hwnd, IDC_PROGRAMS_FOUND)),
- _thread(collect_programs_callback, hwnd, this),
- _sort(_list_ctrl, CompareFunc/*, (LPARAM)this*/)
-{
- TCHAR szTemp[256];
- const size_t nChars = sizeof(szTemp)/sizeof(*szTemp);
- SetWindowIcon(hwnd, IDI_SEARCH);
-
- _resize_mgr.Add(IDC_FILTER, RESIZE_X);
- _resize_mgr.Add(IDC_CHECK_ENTRIES, MOVE_X);
- _resize_mgr.Add(IDC_PROGRAMS_FOUND, RESIZE);
-
- _resize_mgr.Resize(+520, +300);
-
- _haccel = LoadAccelerators(g_Globals._hInstance, MAKEINTRESOURCE(IDA_SEARCH_PROGRAM));
-
- (void)ListView_SetImageList(_list_ctrl, g_Globals._icon_cache.get_sys_imagelist(), LVSIL_SMALL);
-
- LV_COLUMN column = {LVCF_FMT|LVCF_WIDTH|LVCF_TEXT, LVCFMT_LEFT, 250};
-
- LoadString(g_Globals._hInstance, IDS_NAMECOLUMN, szTemp, nChars);
- column.pszText = szTemp;
- ListView_InsertColumn(_list_ctrl, 0, &column);
-
- column.cx = 300;
- LoadString(g_Globals._hInstance, IDS_PATHCOLUMN, szTemp, nChars);
- column.pszText = szTemp;
- ListView_InsertColumn(_list_ctrl, 1, &column);
-
- column.cx = 400;
- LoadString(g_Globals._hInstance, IDS_MENUCOLUMN, szTemp, nChars);
- column.pszText = szTemp;
- ListView_InsertColumn(_list_ctrl, 2, &column);
-
- ListView_SetExtendedListViewStyleEx(_list_ctrl, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
-
- _common_programs = SpecialFolderFSPath(CSIDL_COMMON_PROGRAMS, hwnd);
- if (!_common_programs.empty())
- _common_programs.append(_T("\\"));
-
- _user_programs = SpecialFolderFSPath(CSIDL_PROGRAMS, hwnd);
- if (!_user_programs.empty())
- _user_programs.append(_T("\\"));
-
- CenterWindow(hwnd);
-
- Refresh();
-
- register_pretranslate(hwnd);
-}
-
-FindProgramDlg::~FindProgramDlg()
-{
- _thread.Stop();
-
- unregister_pretranslate(_hwnd);
-}
-
-
-void FindProgramDlg::Refresh(bool delete_cache)
-{
- WaitCursor wait;
-
- _thread.Stop();
-
- TCHAR buffer[1024];
- GetWindowText(GetDlgItem(_hwnd, IDC_FILTER), buffer, COUNTOF(buffer));
- CharLower(buffer);
- _lwr_filter = buffer;
-
- HiddenWindow hide_listctrl(_list_ctrl);
-
- ListView_DeleteAllItems(_list_ctrl);
-
- if (delete_cache || !_thread._cache_valid) {
- _thread.free_dirs();
- _thread.Start();
- } else {
- for(FPDCache::const_iterator it=_cache.begin(); it!=_cache.end(); ++it)
- add_entry(*it);
- }
-}
-
-void FindProgramDlg::collect_programs_callback(Entry* entry, void* param)
-{
- FindProgramDlg* pThis = (FindProgramDlg*) param;
-
- IShellLink* pShellLink;
- HRESULT hr = entry->GetUIObjectOf(pThis->_hwnd, IID_IShellLink, (LPVOID*)&pShellLink);
-
- if (SUCCEEDED(hr)) {
- ShellLinkPtr shell_link(pShellLink);
-
- shell_link->Release();
-
- /*hr = pShellLink->Resolve(pThis->_hwnd, SLR_NO_UI);
- if (SUCCEEDED(hr))*/ {
- WIN32_FIND_DATA wfd;
- TCHAR path[MAX_PATH];
-
- hr = pShellLink->GetPath(path, COUNTOF(path)-1, &wfd, SLGP_UNCPRIORITY);
-
- if (SUCCEEDED(hr)) {
- TCHAR entry_path[MAX_PATH];
-
- entry->get_path(entry_path, COUNTOF(entry_path));
-
- String menu_path;
-
- int len = pThis->_common_programs.size();
-
- if (len && !_tcsnicmp(entry_path, pThis->_common_programs, len))
- menu_path = ResString(IDS_ALL_USERS) + (String(entry_path)+len);
- else if ((len=pThis->_user_programs.size()) && !_tcsnicmp(entry_path, pThis->_user_programs, len))
- menu_path = String(entry_path)+len;
-
- // store info in cache
- FPDEntry new_entry;
-
- new_entry._entry = entry;
- new_entry._menu_path = menu_path;
- new_entry._path = path;
- new_entry._idxIcon = I_IMAGECALLBACK;
-
- pThis->_cache.push_front(new_entry);
- FPDEntry& cache_entry = pThis->_cache.front();
-
- Lock lock(pThis->_thread._crit_sect);
-
- // resolve deadlocks while executing Thread::Stop()
- if (!pThis->_thread.is_alive())
- return;
-
- pThis->add_entry(cache_entry);
- }
- }
- }
-}
-
-void FindProgramDlg::add_entry(const FPDEntry& cache_entry)
-{
- String lwr_path = cache_entry._path;
- String lwr_name = cache_entry._entry->_display_name;
-
- lwr_path.toLower();
- lwr_name.toLower();
-
- if (_lwr_filter.empty())
- if (_tcsstr(lwr_name, _T("uninstal")) || _tcsstr(lwr_name, _T("deinstal"))) // filter out deinstallation links
- return;
-
- if (!_tcsstr(lwr_path, _lwr_filter) && !_tcsstr(lwr_name, _lwr_filter))
- return;
-
- LV_ITEM item = {LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM, INT_MAX};
-
- item.pszText = cache_entry._entry->_display_name;
- item.iImage = cache_entry._idxIcon;
- item.lParam = (LPARAM) &cache_entry;
- item.iItem = ListView_InsertItem(_list_ctrl, &item); // We could use the information in _sort to enable manual sorting while populating the list.
-
- item.mask = LVIF_TEXT;
-
- item.iSubItem = 1;
- item.pszText = (LPTSTR)(LPCTSTR)cache_entry._path;
- ListView_SetItem(_list_ctrl, &item);
-
- item.iSubItem = 2;
- item.pszText = (LPTSTR)(LPCTSTR)cache_entry._menu_path;
- ListView_SetItem(_list_ctrl, &item);
-}
-
-LRESULT FindProgramDlg::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
-{
- switch(nmsg) {
- case WM_CLOSE:
- (void)ListView_SetImageList(_list_ctrl, 0, LVSIL_SMALL); // detach system image list
- goto def;
-
- case PM_TRANSLATE_MSG: {
- MSG* pmsg = (MSG*) lparam;
-
- if (TranslateAccelerator(_hwnd, _haccel, pmsg))
- return TRUE;
-
- return FALSE;}
-
- default: def:
- return super::WndProc(nmsg, wparam, lparam);
- }
-
- return 0;
-}
-
-int FindProgramDlg::Command(int id, int code)
-{
- if (code == BN_CLICKED) {
- switch(id) {
- case ID_REFRESH:
- Refresh(true);
- break;
-
- case IDOK:
- LaunchSelected();
- break;
-
- case IDC_CHECK_ENTRIES:
- CheckEntries();
- break;
-
- default:
- return super::Command(id, code);
- }
-
- return 0;
- }
- else if (code == EN_CHANGE) {
- switch(id) {
- case IDC_FILTER:
- Refresh();
- break;
- }
-
- return 0;
- }
-
- return 1;
-}
-
-void FindProgramDlg::LaunchSelected()
-{
- Lock lock(_thread._crit_sect);
-
- int count = ListView_GetSelectedCount(_list_ctrl);
-
- if (count > 1)
- if (MessageBox(_hwnd, ResString(IDS_LAUNCH_MANY_PROGRAMS), ResString(IDS_TITLE), MB_OKCANCEL) != IDOK)
- return;
-
- for(int idx=-1; (idx=ListView_GetNextItem(_list_ctrl, idx, LVNI_SELECTED))!=-1; ) {
- LPARAM lparam = ListView_GetItemData(_list_ctrl, idx);
-
- if (lparam) {
- FPDEntry& cache_entry = *(FPDEntry*)lparam;
- cache_entry._entry->launch_entry(_hwnd);
- }
- }
-}
-
-int FindProgramDlg::Notify(int id, NMHDR* pnmh)
-{
- switch(pnmh->code) {
- case LVN_GETDISPINFO: {
- LV_DISPINFO* pDispInfo = (LV_DISPINFO*) pnmh;
-
- if (pnmh->hwndFrom == _list_ctrl) {
- if (pDispInfo->item.mask & LVIF_IMAGE) {
- FPDEntry& cache_entry = *(FPDEntry*)pDispInfo->item.lParam;
- Entry* entry = cache_entry._entry;
-
- if (entry->_icon_id == ICID_UNKNOWN)
- entry->_icon_id = entry->extract_icon(ICF_SYSCACHE);
-
- pDispInfo->item.iImage = g_Globals._icon_cache.get_icon(entry->_icon_id).get_sysiml_idx();
- pDispInfo->item.mask |= LVIF_DI_SETITEM;
-
- return 1;
- }
- }}
- break;
-
- case NM_DBLCLK:
- if (pnmh->hwndFrom == _list_ctrl)
- LaunchSelected();
- /*{
- Lock lock(_thread._crit_sect);
-
- LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmh;
- LPARAM lparam = ListView_GetItemData(pnmh->hwndFrom, pnmv->iItem);
-
- if (lparam) {
- FPDEntry& cache_entry = *(FPDEntry*)lparam;
- cache_entry._entry->launch_entry(_hwnd);
- }
- }*/
- break;
-
- case HDN_ITEMCLICK: {
- WaitCursor wait;
- NMHEADER* phdr = (NMHEADER*)pnmh;
-
- if (GetParent(pnmh->hwndFrom) == _list_ctrl) {
- if (_thread._cache_valid) { // disable manual sorting while populating the list
- _sort.toggle_sort(phdr->iItem);
- _sort.sort();
- }
- }
- break;}
- }
-
- return 0;
-}
-
-int CALLBACK FindProgramDlg::CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort)
-{
- ListSort* sort = (ListSort*)lparamSort;
-
- FPDEntry& a = *(FPDEntry*)lparam1;
- FPDEntry& b = *(FPDEntry*)lparam2;
-
- int cmp = 0;
-
- switch(sort->_sort_crit) {
- case 0:
- cmp = _tcsicoll(a._entry->_display_name, b._entry->_display_name);
- break;
-
- case 1:
- cmp = _tcsicoll(a._path, b._path);
- break;
-
- case 2:
- cmp = _tcsicoll(a._menu_path, b._menu_path);
- }
-
- return sort->_direction? -cmp: cmp;
-}
-
-void FindProgramDlg::CheckEntries()
-{
- ///@todo check all entries for existing targets, display a list of not working entries and ask the user for permission to delete them
-}