Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Интерфейс проводника Windows  (Прочитано 29009 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sd
Постоялец

by
Offline Offline

« : 29-03-2012 18:57 » 

Всем добрый вечер.
Задание такое: надо написать интерфейс подобный проводнику Windows. Т.е. приложение с двухпанельным интерфейсом. На левой панели
размещается дерево со списком объектов файловой системы (начиная с корневых каталогов дисков либо с виртуальных системных папок). На правой панели размещается список файлов в каталоге, выбранном в дереве на левой панели.
Решил UI делать с помощью MFC.
На левую панель помещаю Shell Tree Control, на правую - Shell List Control.
Вопрос: как сделать отображение в Shell List Control выделенного диска в Shell Tree Control?
И если есть у кого какие исходники или наработки подобной задачи - поделитесь пожалуйста.
Спасибо.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 29-03-2012 19:45 » 

sd, отработать клик в дереве и по этому событию обновить список.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sd
Постоялец

by
Offline Offline

« Ответ #2 : 29-03-2012 19:52 » 

"Отработать клик в дереве", это, как я понимаю, обрабочик события NM_CLICK. Или TVN_SELCHANGED?
А можно поподробнее, как обновить список Shell List Control?
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 29-03-2012 20:02 » 

"Отработать клик в дереве", это, как я понимаю, обрабочик события NM_CLICK. Или TVN_SELCHANGED?
Скорее, второе.
Цитата
А можно поподробнее, как обновить список Shell List Control?
Очистить содержимое и по одному добавлять новые элементы.
upd: пардон, не обратил внимание, думал, там простой list control. Наверное, надо смотреть куда-то в эту сторону: http://msdn.microsoft.com/en-us/library/bb982541.aspx

Добавлено через 1 минуту и 28 секунд:
upd2. Оказывается, всё можно сделать ещё проще: http://msdn.microsoft.com/en-us/library/bb984429.aspx
« Последнее редактирование: 29-03-2012 20:07 от Вад » Записан
sd
Постоялец

by
Offline Offline

« Ответ #4 : 29-03-2012 20:29 » 

Вад, спасибо!
А может есть подскажете как сделать так, что бы в Shell List Control отображалось только имя папки(файла)? Просто по умолчанию там отображается еще и размер и тип и последнее обновление. Ну и вообще, реально сделать так, что бы отображалось не таблицей, а "плиткой"?
« Последнее редактирование: 29-03-2012 20:31 от sd » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 30-03-2012 08:14 » 

Поскольку всё это хозяйство наследуется от простого CListCtrl - думаю, можно просто установить ему соответствующий стиль: там есть стили и для плитки, и для списка, и для развёрнутого списка. Попробуй посмотреть в сторону метода SetView
Инфо по стилям:
http://msdn.microsoft.com/en-us/library/hfshke78.aspx
http://msdn.microsoft.com/en-us/library/bb774735.aspx#ListView_Styles_and_Views

Ну и в целом, MSDN - надёжный друг и товарищ Ага
Записан
sd
Постоялец

by
Offline Offline

« Ответ #6 : 30-03-2012 08:43 » 

Вад, снова спасибо. Пока что вопросов нету. Будут возникать - буду писать.

Добавлено через 13 часов, 59 минут и 10 секунд:
А подскажите как использовать в Single Document эти компоненты? В диалоговом приложении все ОК, а в Single Document, когда я просто объявляю переменные этих классов в классе CMainFrm, то при запуске программы вылетает ошибка. Т.е. программа отлично компилируется, но не запускается.

Добавлено через 8 часов, 31 минуту и 13 секунд:
Блин, тут еще вопросы возникают, как в диалоговом приложении добавить сплиттер и как сделать привязку моих копмонентов к главному окну? Т.е. что бы при изменении размеров окна изменялся размер и положение компонентов? Хотя лучше бы было вставить эти компоненты в SDI приложение. Но т.к. с MFC до этого не сталкивался - не знаю как это сделать.
« Последнее редактирование: 31-03-2012 07:14 от sd » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 31-03-2012 07:24 » 

sd, мне не совсем понятны твои проблемы. Может разве что:

Но т.к. с MFC до этого не сталкивался - не знаю как это сделать.

Но тогда надо немного с ним познакомится. В мастере проектов, ты сразу можешь создать каркас приложения типа "Проводник", у тебя будет и SDI, и сплиттер, и дерево слева, и список справа. И тд.
Какая у тебя студия?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sd
Постоялец

by
Offline Offline

« Ответ #8 : 31-03-2012 08:57 » 

при создании приложения типа проводник у меня только сплиттер есть, а дерева и списка нет. Студия 10
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 31-03-2012 09:13 » 

Точно нет? Внимательно смотрел? У тебя есть класс CLeftView и класс С***View, где *** - имя проекта?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sd
Постоялец

by
Offline Offline

« Ответ #10 : 31-03-2012 10:46 » 

Оно то есть, но оно не выглядет как, как Shell'ы. Можешь подсказать, как добавить в простое SDI приложение с типом приложения MFC Standart Shell-компоненты?

Добавлено через 11 часов, 46 минут и 4 секунды:
Еще такой вопрос. Мне надо получить путь к файлу(папке) выделенной в списке. На msdn наткнулся на функции
CMFCShellListCtrl::GetItemPath - эта функция позволяет получить путь к выделенному item'у.
Код:
BOOL GetItemPath(
   CString& strPath,
   int iItem
) const;

Вопрос возник как получить индекс выделенного файла(папки)? Оказывается, для этого есть функция CListCtrl::GetHotItem(), но проблема в том, что она все время возвращает -1.
Может сталкивался кто с такой проблемой?

Добавлено через 9 часов, 2 минуты и 28 секунд:
С получением пути к выбранному файлу/папке разрбрался.
Теперь такой вопрос, как удалить файл в корзину? Функция DeleteFile удаляет его вообще безвозвратно.
И как узнать,  что находится по указанному пути, файл или папка?
« Последнее редактирование: 01-04-2012 07:35 от sd » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 01-04-2012 09:33 » 

Посмотри SHFileOperation().
http://exelab.ru/pro/cpp.php?r=filesys&d=zert935
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sd
Постоялец

by
Offline Offline

« Ответ #12 : 01-04-2012 22:53 » 

А есть какие API функции для копирования папок вместе с их содержимым?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 02-04-2012 03:39 » 

Это комплексная операция. Посмотри туда же.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sd
Постоялец

by
Offline Offline

« Ответ #14 : 02-04-2012 22:41 » 

С этим разобрался. А как сделать переименование, такое, как в проводнике. Т.е. имя файла становится возможно отредактировать.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 03-04-2012 03:42 » 

sd, у тебя уже совсем нет фантазии? Поле Edit это.

Кстати, если еще не надоело делать "как" и хочется "лучше чем", то посмотри на Directory Opus. Возможно новые идеи появятся.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sd
Постоялец

by
Offline Offline

« Ответ #16 : 03-04-2012 07:54 » 

Добавил в проект еще 1 диалог, состоящий из Edit и двух копок, для ввода имени папки. При нажатии на кнопку "переименовать", например, появляется новое окно для ввода имени. Вопрос вот в чем, как при нажатии на кнопку ОК передать данные из Edit'a второго диалога, в первое (основное) диалогового окно...Хотя скорее в класс этого окна, т.е. что бы там заполнилась какая-то переменная CString NewName, не используя extern переменных.

Добавлено через 7 часов, 39 минут и 6 секунд:
В общем, создал я в ресурсах новое диалоговое окно с двумя кнопками и Edit'ом. Создал класс для этого диалога CNewNameDlg. В классе главного диалога создал указатель на переменную CNewNameDlg. При нажатии на кнопку "Новая папка" вставил такой код:

Код:
void CFMDlg::OnBnClickedNewfolderbutton()
{
1: m_pNewNameDlg=new CNewNameDlg;

2: if(m_pNewNameDlg->DoModal()==IDOK) {
3: m_pNewNameDlg->NewNameEdit.GetLine(0, m_sNewName.GetBuffer(MAX_PATH), MAX_PATH);
}
    
4: m_ctrlList.GetCurrentFolder(m_sPath);
5: m_sPath+=m_sNewName;

// TODO: Add your control notification handler code here
}

Диалоговое окно появляется, но при нажатии на кнопку ОК, вылазит ошибка (ошибка возникает на строке 3):



может знаете в чем дело?
« Последнее редактирование: 03-04-2012 15:33 от sd » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 03-04-2012 16:17 » 

Думаю, вот это возвращает нулевой указатель:

Код:
m_sNewName.GetBuffer(MAX_PATH)
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sd
Постоялец

by
Offline Offline

« Ответ #18 : 03-04-2012 16:27 » 

Нет. Попробовал щас вставить такую строчку:

m_pNewNameDlg->NewNameEdit.GetLimitText(); d

все равно вылетает

Добавлено через 51 минуту и 45 секунд:
Может есть способы, как можно получить значение переменной одного класса во втором? Пробовал сделать static переменные, но что-то не прокатило, на этапе линковки ошибка какая-то происходит
« Последнее редактирование: 03-04-2012 17:18 от sd » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 03-04-2012 17:32 » 

sd, есть такая вещь — отладчик...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #20 : 03-04-2012 17:46 » 

sd, обрати внимание на строку 1 твоего кода.
Записан
sd
Постоялец

by
Offline Offline

« Ответ #21 : 03-04-2012 18:06 » 

zubr, что в ней не так?
Записан
zubr
Гость
« Ответ #22 : 03-04-2012 18:09 » 

Вызов конструктора объекта.
Записан
sd
Постоялец

by
Offline Offline

« Ответ #23 : 03-04-2012 18:15 » 

Там конструктор пустой. Ну в смысле у класса CNewNameDlg
Записан
zubr
Гость
« Ответ #24 : 03-04-2012 21:04 » 

new CNewNameDlg; или все таки new CNewNameDlg(); ?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 04-04-2012 05:44 » 

zubr, практика показывает, что по крайней мере MS-компилятор расценивает отсутствие скобок в выражении с new как вызов конструктора по умолчанию, если аргументом стоит тип структуры/класса. Как оно там в стандарте - не интересовался даже.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 04-04-2012 07:29 » 

Не в конструкторе дело - раз DoModal отработал, всё конструируется. Дело в обращении к EditBox (или что там такое NewNameEdit) после закрытия диалога. Мне кажется, не факт, что оно будет отзываться на API-функции после закрытия.

sd, заведи себе в диалоге (с помощью соответствующего mfc-мастера) строковую переменную, связанную с твоим Edit-ом, и работай с внешним миром через неё. Ну или не строковую, а что там к делу больше подходит. Ты же диалог закрыл - значит, нельзя полагаться, что в контролах что-то хранится.
Посмотри, как это делают другие диалоги (FileOpenDialog, например)
« Последнее редактирование: 04-04-2012 07:31 от Вад » Записан
sd
Постоялец

by
Offline Offline

« Ответ #27 : 04-04-2012 07:52 » 

Спасибо, с этим разобрался. В принципе сама программа готова и нормально функционирует. Вопрос еще такой есть. У меня в главном окне есть два окна: Shell Tree Control и Shell List Control. При нажати, например, на кнопку "Удалить" мне нGetадо как-то определить, какое из окон сейчас активно и получать путь из этого окна. Как это сделать?
Знаю, что есть функции GetActiveWindow и GetFocus, которые возвращают *CWnd. Но как потом узнать, на что указатель? Пробовал юзать RTTI - безрезультатно.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 04-04-2012 09:52 » 

Метод CWnd::GetDlgCtrlID() вернёт тебе идентификатор контрола. Дальше можно сравнить его с ID твоих списка и дерева, и преобразовывать тип соответственно.
Записан
sd
Постоялец

by
Offline Offline

« Ответ #29 : 05-04-2012 11:24 » new

Парни, программку написал. Всем спасибо за помощь.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines