![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Для начала, попробую задать всем одну простейшею задачку:
Имеем форму Form1, а на ней мемку Memo1 и кнопку Button1. На обработчик OnClick кнопки "повешен" следующий обработчик:
Теперь вопрос: Что будет выведено в Memo1 после нажатия кнопки Button1? Маленькое уточнение. На диске не должно быть файла'c:\Вася\Петя\Лёша\Саша\Маша\Игорь\Дима.lnk' Первому, правильно ответившему, и пояснившему ответ, поставлю + в репутацию :yes: Объяснения и свои комментарии, я напишу позже, если потребуется B) -------------------- Все знать невозможно, но хочется |
|||
|
||||
| Vex |
|
|||
![]() кацапосрачмученiкъ ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3103 Регистрация: 28.3.2002 Где: strawberry fields Репутация: 1 Всего: 88 |
''
c:\Вася\Петя\Лёша\Саша\Маша\Игорь\Дима.lnk угадал? -------------------- Слава Україні. |
|||
|
||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Нет. если-бы все так просто, я бы и писать не стал.
-------------------- Все знать невозможно, но хочется |
|||
|
||||
| <Spawn> |
|
|||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Сейчас особенно нет времени разбираться, так как пора спать, но эффект весьма странный - выдирается иконка из shell32.dll. Причем такая, как если бы это был пустой ярлык, не ассоциированый с реальным файлом на диске. Возможно это и есть обьяснение ее логики работы, так как данного ярлыка не существует
П.С. Спокойной ночи Не - тут чего то не то Это сообщение отредактировал(а) <Spawn> - 14.7.2004, 21:42 -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
|||
|
||||
| AriX |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 16.6.2003 Репутация: 5 Всего: 19 |
выводится два раза путь к shell32.dll
предположение такое: так как по-умолчанию типа String это AnsiString - то в s1 хранится не сама строка, а указатель.. дальше в s2 пихается этот же указатель ну ту же строку... потом мы pchar'им s1 - но PChar это тоже указатель на строку.. в итоге получается так что если файла не существует, то ExtractAssociatedIcon (вот тут могу ошибаться) наверное возвращает пустую иконку (типа для несуществующего файла) из стандартного набора иконок (shell32.dll), а в s1 (т.е. туда куда он указывает) пихает путь к файлу с этими иконками (он типа ассоциирован с не существующими файлами)... а так как s2 ссылается на ту же область что и s1, то вторая строка в мемо получается такой же может плохо объяснил - но если на пальцах - то так Это сообщение отредактировал(а) AriX - 14.7.2004, 22:59 |
|||
|
||||
| Alex |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4147 Регистрация: 25.3.2002 Где: Москва Репутация: 80 Всего: 162 |
Ну а что тут объеснять в MSDN написано
Из чего следует, что вам вернули путь до файла, из которого вам взяли иконку. В данном случае к shell32.dll, в которой храниться иконка пустого файла. Но на сколько я понимаю вас возмущает не это, а то, что в s2 тоже изменяется значение. Ну, вообще-то это очень странно, но объяснение этому есть т. к. это указатель на адрес памяти, где хранятся значения переменных, и когда вы пишите s2:= s1; то просто увеличивается счетчик ссылок на это значение. Соответственно когда изменяется значение переменной s1, то эти данные должны положиться по новому адресу чтобы значение s2 осталось неизменным, но Microsoft по необъяснимым причинам кладет их по старому адресу тем самым, затирая значения в s2. Решение проблемы:
-------------------- Написать можно все - главное четко представлять, что ты хочешь получить в конце. |
||||
|
|||||
| AriX |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 16.6.2003 Репутация: 5 Всего: 19 |
млин, пока изменял свой пост - уже ответили
|
|||
|
||||
| Петрович |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Про s1 и s2 все правильно рассказали.
Но, теперь, самое интересное: попробуйте вместо:
написать:
-------------------- Все знать невозможно, но хочется |
||||
|
|||||
| AriX |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 311 Регистрация: 16.6.2003 Репутация: 5 Всего: 19 |
ага точно - пробовал, там меньше чем c:\Вася\Петя\Лёша\Саша уже не напишешь
|
|||
|
||||
| Girder |
|
||||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
Петрович просто все плохо
Лови:
Кстати, приколись:
-------------------- Как слышим, так и пишим. Истина где-то там... |
||||
|
|||||
| Петрович |
|
||||||||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Если-бы я этого не знал, то разве стал-бы писать:
1. А где там написан размер буфера? 2. Поскольку ответ найден, теперь приведу свой вариант Для начала, фрагмент описания ExtractAssociatedIcon из MSDN:
Красным выделил неувязочку в MSDN. Т.е. про параметр lpIconPath сказано что он только входной ([in]), а ниже сказано что в строку на которую он указывает, возвращается путь до файла содержащего икону. Причем, нигде не сказанно, какого размера будет возвращаемая строка! Обычно, если API функция возвращает строку в буфер предоставляемый программой (как в данном случае) ей на вход, помимо указателя на буфер передают и его размер. Это для того, что-бы она не вышла за его границу. Здесь-же мы такого не видим. Можно было-бы предположить, что размер буфера определяется по размеру переданной в этом параметре строки. Но, это не так. Реально, Windows наглым образом копирует по переданному указателю столько байт, сколько им захочется! Т.е., легко переваливает за буфер! Именно поэтому, я и передаю такое длинное имя в первом примере - что-бы не было AV. Во втором варианте, передача короткого имени приводит к тому, что результирующая строка превышает размер выделенной под s1 памяти. Обычно это приводит к AV, причем иногда не сразу. Теперь, посмотрим как используется данная функция в Delphi программах. Например, из FAQ:
Причем, подобное встречал и в других текстах. Казалось-бы, в свете вышесказанного, это должно приводить к AV. Почему-же никто еще об это не споткнулся? Да все очень просто. Обычно, к ExtractAssociatedIcon обращаются с именем существующего файла. А в этом случае, она возвращает именно это имя обратно - т.е. не выходит за "габариты" переданной строки. Я же, наткнулся на это случайно. Просто из-за ошибки в своей программе, я передал туда имя несуществующего линка (просто без пути Резюме. Надо передавать в ExtractAssociatedIcon вторым параметром строку размещенную в буфере достаточного размера. Вопрос только какого. Поскольку в MSDN ничего об этом не сказано, можно лишь предложить что-то вроде MAX_PATH. Соответственно, вот пример кода (функцианально похож на код приведенный Girderом):
Он работает нормально. Проверено. Просьба к Vitу - подправь пожалуйста в FAQ Добавлено @ 11:05 Да, к стати:
У меня тоже не проходит. Дело в том, что у меня setlength(s1,Max_Path); переносит завершающий #0 в новый конец строки. Поэтому, если передавать имя реально существующего имени файла, то он его все равно не находит -------------------- Все знать невозможно, но хочется |
||||||||||||||
|
|||||||||||||||
| Girder |
|
||||
![]() Лентяй 2 ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1993 Регистрация: 12.5.2004 Репутация: 31 Всего: 155 |
-------------------- Как слышим, так и пишим. Истина где-то там... |
||||
|
|||||
| Петрович |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1000 Регистрация: 2.12.2003 Где: Москва Репутация: 25 Всего: 55 |
Ну да, можно и так.
-------------------- Все знать невозможно, но хочется |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |