|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
В VB6 использовал следующую ф-цию (привожу целиком под спойлером -заумный бюрократический вариант): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101.
Т.е. код сводится к Код: vbnet 1. 2.
Иконка 981 -я обычно беру иконку с 6-ю вариантами картинок: 32x32 (32бит, 256цветов, 16 цветов) + 16x16 (32бит, 256цветов, 16 цветов) Суть ф-ции сводится к следующему(как я понимаю): 1) Ф-ция высчитывает метрики системы (SM_C<X,Y>ICON -хотя очевидно что это 32х32, SM_C<X,Y>SMICON -очевидно что это 16х16) 2) Вытаскивает эти иконки через LoadImage function LoadImageAsString(имя ресурса, желаемый размер cx-cy согласно метрикам) после чего имеем хэндлы иконок hIconLarge и hIconSmall 3) Тупо шлем эти иконки в сторону целевого окна: Код: vbnet 1. 2.
В .Net я эту иконку MY_ICON 32x32 (32бит, 256цветов, 16 цветов) + 16x16 (32бит, 256цветов, 16 цветов) кладу в MyResources. Более удобная реализация ресурсов, но ДРУГАЯ. Кто б спорил. Если надо установить иконку СВОЕГО окна, то вообще без проблем: Код: vbnet 1.
и оно само разберется где там big, где там small. Но если окно чужое, то очевидно (поправьте если чего не знаю) что без вариантов WM_SETICON И вот я не могу понять, как правильно выскрести hIconLarge (SM_C<X,Y>ICON =32х32 ?) hIconSmall (SM_C<X,Y>SMICON =16х16 ?) из My.Resources.MY_ICON LoadImage (API) работает ведь с классическими ресурсами, а не с .Net-овскими, в лоб не перекатаешь. Один вариант (грубый) я вроде как вижу: Засунуть в .Net ресурсы 2 иконки вместо одной (по одной картинке в каждой) MY_ICON_32 (32бит) MY_ICON_16 (32бит) Тогда Код: vbnet 1. 2.
Но он базируется на 1) Использовании 2-х иконок вместо одной 2) Аксиоматического предположения про 32х32 и 16х16 вместо SystemMetrics Как бы это пограмотней сделать? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 16:27 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Ну я в принципе вот так подправил: Применение: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.
P.S. 1) Применение для СВОИХ окон - не планируется 2) Применение для установки иконки всего приложения (bSetAsAppIcon=True) -не планируется Вопросы: Должен ли я заботиться об освобождении ресурсов для 1) New Icon( ... As Icon 2) hIconLarge и hIconSmall= .New Icon(...) .Handle ??? По идее объект New Icon должен вроде убиться и освободить ресурсы по выходу из ф-ции SetIcon() Если верить комментарию к WM_SETICON message : Notes* The system does not make a copy of the icon. Do not destroy the icon before destroying the window. то New Icon() не рушится по выходу из SetIcon() потому что все работает и установленная иконка никуда не девается. Отсюда вопрос. Должен ли я принимать какие-то дополнительные действия к освобождению ресурсов связанных с выдернутыми иконками? P.S. Вменяемого аналога для GetSystemMetrics в .Net не нашел. Как вариант можно просто подставлять цифры 16 и 32 ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 19:07 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
По поводу освобождения ресурсов: Вот так не работает (понятно почему): Код: vbnet 1. 2. 3. 4.
Вот так на первый взгляд работает, но стоит свернуть окно на панель задач/развернуть, установленная иконка заменяется оригинальной: Код: vbnet 1. 2. 3. 4.
Отсюда вывод - где-то надо делать IconSmall.Dispose() (при закрытии главной формы?) и следить за этим, если например ф-ция вызывается дважды. Либо тупо использовать 2 иконки (числа 16 и 32 брать на веру) и обращаться к My.Resource.MY_ICON_32.handle и My.Resource.MY_ICON_16.handle (что очевидно очистки не требует). ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 19:56 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77, IconSmall.Dispose() убьёт икону и сделает хэндл невалидным. Мусоросборщик сдедает то же самое но чуть позже ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 21:11 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
ИзопропилIconSmall.Dispose() убьёт икону и сделает хэндл невалидным. Естественно. Это были тесты. ИзопропилМусоросборщик сдедает то же самое но чуть позже Слыхал про такого. Т.е. ты хочешь сказать что надо оставить код в первоначальном варианте и довериться этому "мусоросборщику"? Так? Просто я уже придумал новый (более аккуратный) вариант кода (речь идет об окне хэлпа чтоб было понятней): Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63.
Негативчик в том, окно хэлпа закрывается на долю секунду позже чем срабатывает мой "код очистки" и может промелькнуть оригинальная иконка. Оставить первый вариант вообще без Dispose()? Там есть еще момент, что окно help может вызываться и закрываться несколько раз в процессе работы приложения и иконка будет каждый раз новая ("поверх старой"). Ваш "сборщик" с этим справится? Это код сборщика мусора? Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 21:44 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
ИзопропилМусоросборщик сдедает то же самое но чуть позже Почитал я чуток про этого чудо-сборщика. Но тогда другой вопрос. Где гарантия, что это "чуть позже" не наступит "чуть раньше" чем НАДО? Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8.
Область видимости New Icon ограничивается ф-цией SetIcon Сборщику вряд ли что-либо известно про WM_SETICON, про мое окно htmlHelp, закрыли ли его уже или нет, про то что New Icon еще нужна. Он ее возьмет и грохнет в любой момент. И будет тоже самое что во втором тесте , но "чуть позже". Следуя этой логике, я бы оставил второй вариант кода, где "New Icon" иконки "видимы" до конца работы приложения Код: vbnet 1. 2.
Но убрал бы собственный "код очистки" в Form1_FormClosed, рассчитывая на "уборку" при закрытии App. Покритикуешь? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 22:36 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77Где гарантия, что это "чуть позже" не наступит "чуть раньше" чем НАДО? Наступит! У Рихтера пример с таймером на сей счёт имеется. после этой строки мусоросборщик имеет полное право грохнуть Icon Код: vbnet 1.
забыть про область видимости идентификаторов, к сборке мусора это отношения не имеет. Запомнить ссылку на Icon нужно, например в статической переменной(ли другом месте до которого мусоросборщик не доберётся ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 23:19 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77Это код сборщика мусора? НЕТ! бегом Рихтера читать! ... |
|||
:
Нравится:
Не нравится:
|
|||
13.10.2013, 23:31 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Изопропилзабыть про область видимости идентификаторов, к сборке мусора это отношения не имеет. Запомнить ссылку на Icon нужно, например в статической переменной(ли другом месте до которого мусоросборщик не доберётся Не забыл, с самого начала поставил под сомнение правомерность конструкции Код: vbnet 1.
И очень удивился тому что код работает. А это могло быть только по двум причинам: 1) WM_SETICON все-таки делает копию (комментарий приведенный в документации на WM_SETICON не есть документация, и вполне мог быть ошибочным утверждением того кто это дописал) 2) Объект Icon не уничтожается по выходу из ф-ции. Тест явно показал, что утверждение из MSDN верное, а объект сам не уничтожается. А раз не уничтожается, значит его надо уничтожить (самому) - опыт есть, поэтому за такими вещами предпочитаю следить даже по мелочам. А про всяких там "сборщиков" извините не думал, не привык на них рассчитывать. Ну, тогда, Дмитрий77...я бы оставил второй вариант кода, где "New Icon" иконки "видимы" до конца работы приложения Код: vbnet 1. 2.
Но убрал бы собственный "код очистки" в Form1_FormClosed, рассчитывая на "уборку" при закрытии App... ИзопропилДмитрий77Это код сборщика мусора? НЕТ! бегом Рихтера читать! Да понял я и без Рихтера идею этого сборщика, иначе б не задал. этого вопросаГде гарантия, что это "чуть позже" не наступит "чуть раньше" чем НАДО? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 00:08 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77А про всяких там "сборщиков" извините не думал, не привык на них рассчитывать. придётся привыкать и взаимодействовать с ними Дмитрий772) Объект Icon не уничтожается по выходу из ф-ции. да. выход идентификатора из области вмдимости и процесс сборки мусора никак не связаны Дмитрий77А раз не уничтожается, значит его надо уничтожить (самому) - опыт есть, поэтому за такими вещами предпочитаю следить даже по мелочам. Старый опыт здесь неприменим. Что имеет смысл делать руками -вызывать Dispose() у тех, кто реализует IDisposable ( явно или посредством конструкции using) P.S. Может сначала Рихтера, а? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 00:24 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77рассчитывая на "уборку" при закрытии App.. По-хорошему, при закрытии приложения самому подчистить неуправляемые ресурсы нужно ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 00:26 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
ИзопропилДмитрий77рассчитывая на "уборку" при закрытии App.. По-хорошему, при закрытии приложения самому подчистить неуправляемые ресурсы нужно OK, я не против и всегда это делал. В VB6 для этого Form_Unload Здесь я использую Код: vbnet 1. 2. 3. 4. 5. 6. 7.
Но при этом сталкиваюсь с эффектом: Дмитрий77Негативчик в том, окно хэлпа закрывается на долю секунду позже чем срабатывает мой "код очистки" и может промелькнуть оригинальная иконка. Это наводит меня на мысль, что Form1_FormClosed (основной формы) не лучшее место и не конечная инстанция где это можно сделать. Где тогда я должен "подчищать"? ИзопропилСтарый опыт здесь неприменим. Что имеет смысл делать руками -вызывать Dispose() у тех, кто реализует IDisposable ( явно или посредством конструкции using). Думаю местами применим и необходим. Для .Net -объектов -ДА, но если я использую Код: vbnet 1.
то я просто обязан сделать Код: vbnet 1.
Уборщик за меня это точно не сделает, он очевидно "не знает" что это такое. Т.е. в данном примере я обязан руководствоваться документацией MSDN а не документацией .NET. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 00:49 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77OK, я не против и всегда это делал. В VB6 для этого Form_Unload Дмитрий77 Где тогда я должен "подчищать"? Почему Form_Unload а не Application_ApplicationExit ? Никакой "главной" формы в net приложении нет. Дмитрий77Уборщик за меня это точно не сделает, он очевидно "не знает" что это такое. Уборщику можно помочь. См класс SafeHandle, но сначала - Рихтера Дмитрий77Думаю местами применим и необходим. Скорее вреден. Подсчёт ссылок в стиле COM (VB/VBA) не производится, для взаимодействия с COM - другие механизмы - RCW,CCW Семантика финализатора радикально отличается от деструктора с++ ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 01:09 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77Т.е. в данном примере я обязан руководствоваться документацией MSDN а не документацией .NET. Ошибка. Документация NET входит в MSDN. А вот без понимания работы мусоросборщика можно много дров наломать при использовании неуправляемого API ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 01:13 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
Дмитрий77, обрати ещё внимание на GC.KeepAlive и посмотри на пример в MSDN ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 01:23 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
ИзопропилПочему Form_Unload а не Application_ApplicationExit ? Потому что я не знал про Application_ApplicationExit. И оно не лежит на поверхности. Погляди, так правильно? Портачить в служебных файлах (которые по команде "Показать все файлы") я не рискнул Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Но все же я б не рискнул запихивать туда "все что можно", сдуру это было сделал например сохранять положение и размеры формы в реестре думаю надо таки из Form1_FormClosed формы о кот. речь(по очевидным причинам). ИзопропилНикакой "главной" формы в net приложении нет. Да, но есть "начальная форма" Проект -> Свойства -> Приложение и как правило когда она закрывается, то закрывается приложение. (хотя обеспечить его закрытие - чтоб другие формы случайно не висели и т.д. - это и моя задача тоже) Просто когда я задавал вопрос про Sub Main() -стандартный прием в VB6, когда до загрузки формы делаешь действия по типу Код: vbnet 1. 2. 3. 4. 5.
то я натолкнулся на нек. непонимание (или кто-то там до меня натолкнулся в похожем посте). Тогда вопрос: Куда я могу засунуть те действия ДО ЗАГРУЗКИ ФОРМЫ (до Form_Load), пример которых я привел выше. Может я на основании "предварительных результатов" хочу селективно вообще отказаться от загрузки формы, сделать какие-то действия и завершить приложение. Application_ApplicationExit -вроде как разобрались. А что тогда есть Application_ApplicationStart? ИзопропилОшибка. Документация NET входит в MSDN.Не цепляйся. Имелось ввиду то, что в Google обычно отображается с ключевыми словами (Windows) - MSDN - Microsoft а не ( System.что-то там ) - MSDN - Microsoft Код: vbnet 1. 2.
Посмотрел, но не хочу сейчас в это сильно влезать. Тяжело для понимания. Как и злоупотребление Marshal-ом. Про сборщика пару основных идей я вроде как понял. То же про Рихтера. Я начал было честно читать CLR via C# - но довольно быстро обнаружил что я перестал понимать большую часть из того что читаю, а когда мозг отказывается воспринимать, то вряд ли это на пользу. Поэтому я ее пока отложил в сторону. Было б у него тоже самое хотя б на примере VB.NET написано, м.б. проще понималось бы. Не знаю, но пока есть чем заниматься. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 03:09 |
|
Установка иконки "чужого" окна
|
|||
---|---|---|---|
#18+
авторКуда я могу засунуть те действия ДО ЗАГРУЗКИ ФОРМЫ (до Form_Load) Никакой мистики нет. Бейсик автоматом генерит Public Sub Main() со стандартным открытием одинокой "главеной" формы . В свойствах проекта сними флажок Enable application framework и сделай свою процедуру Main Пример с ApplicationContext - http://msdn.microsoft.com/en-us/library/vstudio/System.Windows.Forms.ApplicationContext(v=vs.100).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1 ... |
|||
:
Нравится:
Не нравится:
|
|||
14.10.2013, 10:21 |
|
|
start [/forum/topic.php?fid=20&tid=1403878]: |
0ms |
get settings: |
11ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
74ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
53ms |
get tp. blocked users: |
2ms |
others: | 14ms |
total: | 189ms |
0 / 0 |