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

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

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

« : 10-10-2009 21:38 » 

Привет)

Помогите, пожалуйста, как программно получить координаты ярлычков, расположенных на рабочем столе?

И как вообще залезать в папку "Рабочий стол", ведь нужно узнать имя пользователя, а так же, какой язык используется, я правильно понимаю?

Я думаю, надо залезть в папку "рабочий стол", прочитать все файлы, расположенные в ней, только, где хранятся координаты ярлыков и файлов (папок), расположенных на "столе"?

Записан
Serg79
Команда клуба

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

WWW
« Ответ #1 : 11-10-2009 07:21 » 

The Nameless One, смотри переменные окружения.
Записан
The Nameless One
Помогающий

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

« Ответ #2 : 11-10-2009 07:48 » 

Что такое "переменные окружения"?
Записан
Serg79
Команда клуба

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

WWW
« Ответ #3 : 11-10-2009 07:55 » 

Что такое "переменные окружения"?
Набери команду set в консоле (cmd) и ты их увидешь.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #4 : 11-10-2009 07:56 » 

The Nameless One,

Для наглядности и скорости:
cmd.exe
> set


У каждого процесса есть набор этих переменных. Большинство из них устанавливаются при создании процесса и копируются из родительского процесса. Для (наверно) всех API и языков есть возможность получать их список, получать и изменять значения отдельных переменных, создавать новые и удалять существующие.

Serg79 опередил Улыбаюсь

В общем, это текстовые пары имя-значение.
В винде есть набор полезных переменных. Тебе нужна USERPROFILE - там путь к папке с профилем, а от нее уже можно дойти до папки "Рабочий стол". Только использовать название "Рабочий стол" не следует, т.к. в зависимости от настроек системы оно может меняться - имя папки надо взять в реестре: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Desktop.

Э... несколько запутался.
К примеру, у меня в этом ключе реестра значение "%USERPROFILE%\Desktop". Выражение типа "%USERPROFILE%" означает, что это переменная окружения "USERPROFILE" и его надо заменить значением этой переменной. Так получится полный путь к искомой папке.
« Последнее редактирование: 11-10-2009 08:07 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
The Nameless One
Помогающий

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

« Ответ #5 : 11-10-2009 08:07 » 

Большое вам спасибо, пойду разбираться)
Записан
The Nameless One
Помогающий

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

« Ответ #6 : 11-10-2009 08:12 » 

Подскажите, пожалуйста, как программно получить значение из реестра HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Desktop?

Записан
RXL
Технический
Администратор

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

WWW
« Ответ #7 : 11-10-2009 08:15 » 

Сперва читаешь значение из реестра, а потом обрабатываешь его ExpandEnvironmentStrings().

http://msdn.microsoft.com/en-us/library/ms724875%28VS.85%29.aspx
Registry Functions

http://msdn.microsoft.com/en-us/library/ms724265%28VS.85%29.aspx
ExpandEnvironmentStrings Function


О работе с реестром можно почитать тут: Работа с реестром Windows.
« Последнее редактирование: 11-10-2009 08:17 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
The Nameless One
Помогающий

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

« Ответ #8 : 11-10-2009 08:19 » 

В общем, разберусь с переменными окружения и смогу создать папку в профайле юзера (иначе, как я понял, ОС может запретить моей программе создавать файл вне этой папке, если у пользователя нет админских прав, я правильно говорю?)

Насчет ярлычков и их координат вот поиском нашел:

Код:
#include <commctrl.h>

 //получаем хэндл рабочего стола как бы, потом хэндлы дочерних элементов  ...
 HANDLE r=FindWindow("ProgMan",NULL);
 r= GetWindow(r, GW_CHILD);
 r= GetWindow(r, GW_CHILD);

 //получаем количество иконок на рабочем столе
 int cnt=SendMessage(r,LVM_GETITEMCOUNT,0,0);
 //отправляя сообщение LVM_GETITEMTEXT, можем узнать имя иконки,
 третьим параметром для SendMessage указываем номер иконки.
 Здесь точно не скажу как сделать, читал что так просто имя иконки не взять, нужно читать с памяти другого процесса,
 но добить это дело не хватило терпения)))
 
 TPoint xy;     //здесь будем хранить позицию иконки
 SendMessage(r,LVM_GETITEMPOSITION,i,(LONG)&xy);  //запишет в xy позицию иконки с номером i
 //изменяя xy.x и xy.y , зададим новую позицию
 SendMessage(r,LVM_GETITEMPOSITION,i,(LONG)&xy);  //и установим для иконки новую позицию на столе))

Скажите, пожалуйста, почему r= GetWindow(r, GW_CHILD); два раза?
Записан
The Nameless One
Помогающий

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

« Ответ #9 : 11-10-2009 08:20 » 

RXL, большое спасибо!
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #10 : 11-10-2009 08:29 » 

The Nameless One, рабочие папки для программы надо создавать в AppData или Local AppData (первое обычно используют для настоек и необходимых для программы файлов, но индивидуальных для данного пользователя, а второе - для часто меняющихся данных).


Про GetWindow: косвенность - сперва находится потомок окна "ProgMan", а потом уже его потомок.
http://msdn.microsoft.com/en-us/library/ms633515%28VS.85%29.aspx
« Последнее редактирование: 11-10-2009 08:33 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
The Nameless One
Помогающий

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

« Ответ #11 : 11-10-2009 08:33 » 

Всё понятно)

Значит для файлов свой программы лучше создать папку в Application Data, которую нужно узнать из реестра.

Спасибо большое за помощь!


ЗЫ "ProgMan" - это всегда рабочий стол?
« Последнее редактирование: 11-10-2009 08:35 от The Nameless One » Записан
Вад
Команда клуба

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

« Ответ #12 : 11-10-2009 09:27 » 

Значит для файлов свой программы лучше создать папку в Application Data, которую нужно узнать из реестра.
Не обязательно лезть в реестр. Есть специальная функция, которая вернёт этот путь по CSIDL-идентификатору специальной директории: SHGetSpecialFolderLocation. Значения CSIDL - CSIDL_APPDATA для конкретного пользователя и CSIDL_COMMON_APPDATA для всех пользователей. См. также SHGetFolderPath - она, пожалуй, поудобнее будет.
« Последнее редактирование: 11-10-2009 09:33 от Вад » Записан
The Nameless One
Помогающий

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

« Ответ #13 : 11-10-2009 11:05 » 

Вад, большое спасибо за помощь!
Записан
The Nameless One
Помогающий

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

« Ответ #14 : 11-10-2009 17:05 » 

Можно как-нибудь преобразовать char *fPath, полученный функцией  SHGetFolderPath, чтобы этот путь можно было использовать для С++ файловой системой ввода-вывода?
std::oftream MyFile(fPath);
При этом fPath должен содержать двойную косую черту, C:\\mydir\\filename, а после SHGetFolderPath черта одна.
Записан
Вад
Команда клуба

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

« Ответ #15 : 11-10-2009 17:31 » new

Двойная черта нужна только при определении констант, поскольку одиночная используется для задания escape-последовательностей. Во внутреннем представлении строки черта будет одиночная, тут должно быть всё ОК.
Записан
The Nameless One
Помогающий

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

« Ответ #16 : 11-10-2009 17:41 » 

Не хочет создаваться или открываться файл по fPath, странно.
Только если CreateFile использовать.
А желательно ofstream.
В чем же дело?
« Последнее редактирование: 11-10-2009 17:47 от The Nameless One » Записан
RXL
Технический
Администратор

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

WWW
« Ответ #17 : 11-10-2009 18:00 » 

The Nameless One, удвоение бекслеша нужно лишь в константах в исходниках C++, т.к. бекслеш используется для вставки спецсимволов и экранирования кавычек, но в самой строке удвоение быть не должно.
Записан

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

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

« Ответ #18 : 11-10-2009 20:17 » 

Хм. У меня пока только одна идея: возможно, проблема с Unicode. Точнее, SHGetFolderPath возвращает путь в unicode, а ты пытаешься использовать ascii-шный ofstream?
Записан
The Nameless One
Помогающий

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

« Ответ #19 : 11-10-2009 21:51 » 

В настройках проекта поставил multibyte вместо unicode. Значит из-за этого?
« Последнее редактирование: 11-10-2009 22:22 от The Nameless One » Записан
The Nameless One
Помогающий

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

« Ответ #20 : 11-10-2009 22:10 » 

Как преобразовать из unicode в ascii для ofstream?
« Последнее редактирование: 12-10-2009 10:16 от The Nameless One » Записан
The Nameless One
Помогающий

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

« Ответ #21 : 13-10-2009 21:09 » 

Если кому-то интересно:

проблема была в том, что в пути содержались русские буквы.
Нужно лишь было сделать так перед открытием файла:

Код:
setlocale(LC_ALL,"Russian");
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines