powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
9 сообщений из 9, страница 1 из 1
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253188
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело в следующем. В приложении вместо системных MsgBox используются свои собственные сообщения, но иконки берутся системные таким способом:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
Dim hIcon As Long
Dim hIcon2 As Long
Dim hIcon3 As Long
'так
hIcon = LoadIcon(0, IDI_EXCLAMATION)
DrawIcon Picture1.hDC, 0, 0, hIcon
'или так
hIcon2 = LoadIcon(0&, IDI_EXCLAMATION)
DrawIconEx Picture2.hDC, 0, 0, hIcon2, 0, 0, 0&, 0&, DI_NORMAL
'еще вот так
hIcon3 = LoadIcon(0&, IDI_EXCLAMATION)
DrawIconEx Picture3.hDC, 0, 0, hIcon3, 48, 48, 0&, 0&, DI_NORMAL



Проблема в том, что на 7 винде при размере системных шрифтов 150% иконки таким макаром рисуются мелкие и растягиваются, в то время, как системное MsgBox "Test", vbExclamation выдает нормальную крупную.
Прилагаю тестовый примерчик, для проверки надо увеличить шрифт системы до 150% и нажать тестовую кнопку для вызова системного сообщения или можно со скриншотом сравнить, который в главное окно вставил. Выдранные иконки будут мелкими, две из них растянуты до 48, а системная в сообщении будет крупная и нормальная.
Есть идеи, как получить крупную иконку программно?

...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253213
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pantalone,

LoadIcon function

LoadIcon can only load an icon whose size conforms to the SM_CXICON and SM_CYICON system metric values.

То бишь у тебя есть только 16x16 и 32х32

Код: vbnet
1.
DrawIconEx Picture3.hDC, 0, 0, hIcon3, 48, 48, 0&, 0&, DI_NORMAL


Ну это ты просто растягиваешь наверно 32х32 до 48х48.

Вытаскивай эту иконку с размером 48x48 откуда-нибудь (с 32-битными цветами ясно дело - в VB6 только через ResHaker и т.п.) и пихай в ресурсы, потом делай LoadImage.
Хотя ты ж хочешь "системную". А на 8.1 и на 10 она уже будет другая.

А вообще
авторВ приложении вместо системных MsgBox используются свои собственные сообщения

ИМХО, а на фига, сообщения "свои" а иконку хочу "системную". Используй тогда уж системные сообщения и не морочь себе голову. А если масштаб не 150 а 200 а 300, что будешь делать? 64х64 и 96х96 пытаться выуживать?
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253215
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да уж. А из ресурсов системы тоже толком не вытащить, хотя размер в этом случае нормальный получается, но Windows 7 в Shell32.dll нашел кучу значков с восклицательным знаком, а в XP таких в этой библиотеке нет ни одной.
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253221
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pantalone,

Попробуй еще с вот этим поиграться

SHGetStockIconInfo function

SHSTOCKICONID enumeration

SIID_WARNING - это твоя иконка

Немного кода в помощь:

Код: 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.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
'http://www.peschuster.de/2011/12/how-to-add-an-uac-shield-icon-to-a-menuitem/
'http://msdn.microsoft.com/en-us/library/windows/desktop/bb762205(v=vs.85).aspx
'http://msdn.microsoft.com/en-us/library/windows/desktop/bb762542(v=vs.85).aspx
'http://msdn.microsoft.com/en-us/library/windows/desktop/bb759805(v=vs.85).aspx
'>=Vista only

'Shell Constants, Enumerations, and Flags
Public Enum SHSTOCKICONID
  SIID_DOCNOASSOC = 0
  SIID_DOCASSOC = 1
  SIID_APPLICATION = 2
  SIID_FOLDER = 3
  SIID_FOLDEROPEN = 4
  SIID_DRIVE525 = 5
  SIID_DRIVE35 = 6
  SIID_DRIVEREMOVE = 7
  SIID_DRIVEFIXED = 8
  SIID_DRIVENET = 9
  SIID_DRIVENETDISABLED = 10
  SIID_DRIVECD = 11
  SIID_DRIVERAM = 12
  SIID_WORLD = 13
  SIID_SERVER = 15
  SIID_PRINTER = 16
  SIID_MYNETWORK = 17
  SIID_FIND = 22
  SIID_HELP = 23
  SIID_SHARE = 28
  SIID_LINK = 29
  SIID_SLOWFILE = 30
  SIID_RECYCLER = 31
  SIID_RECYCLERFULL = 32
  SIID_MEDIACDAUDIO = 40
  SIID_LOCK = 47
  SIID_AUTOLIST = 49
  SIID_PRINTERNET = 50
  SIID_SERVERSHARE = 51
  SIID_PRINTERFAX = 52
  SIID_PRINTERFAXNET = 53
  SIID_PRINTERFILE = 54
  SIID_STACK = 55
  SIID_MEDIASVCD = 56
  SIID_STUFFEDFOLDER = 57
  SIID_DRIVEUNKNOWN = 58
  SIID_DRIVEDVD = 59
  SIID_MEDIADVD = 60
  SIID_MEDIADVDRAM = 61
  SIID_MEDIADVDRW = 62
  SIID_MEDIADVDR = 63
  SIID_MEDIADVDROM = 64
  SIID_MEDIACDAUDIOPLUS = 65
  SIID_MEDIACDRW = 66
  SIID_MEDIACDR = 67
  SIID_MEDIACDBURN = 68
  SIID_MEDIABLANKCD = 69
  SIID_MEDIACDROM = 70
  SIID_AUDIOFILES = 71
  SIID_IMAGEFILES = 72
  SIID_VIDEOFILES = 73
  SIID_MIXEDFILES = 74
  SIID_FOLDERBACK = 75
  SIID_FOLDERFRONT = 76
  SIID_SHIELD = 77
  SIID_WARNING = 78
  SIID_INFO = 79
  SIID_ERROR = 80
  SIID_KEY = 81
  SIID_SOFTWARE = 82
  SIID_RENAME = 83
  SIID_DELETE = 84
  SIID_MEDIAAUDIODVD = 85
  SIID_MEDIAMOVIEDVD = 86
  SIID_MEDIAENHANCEDCD = 87
  SIID_MEDIAENHANCEDDVD = 88
  SIID_MEDIAHDDVD = 89
  SIID_MEDIABLURAY = 90
  SIID_MEDIAVCD = 91
  SIID_MEDIADVDPLUSR = 92
  SIID_MEDIADVDPLUSRW = 93
  SIID_DESKTOPPC = 94
  SIID_MOBILEPC = 95
  SIID_USERS = 96
  SIID_MEDIASMARTMEDIA = 97
  SIID_MEDIACOMPACTFLASH = 98
  SIID_DEVICECELLPHONE = 99
  SIID_DEVICECAMERA = 100
  SIID_DEVICEVIDEOCAMERA = 101
  SIID_DEVICEAUDIOPLAYER = 102
  SIID_NETWORKCONNECT = 103
  SIID_INTERNET = 104
  SIID_ZIPFILE = 105
  SIID_SETTINGS = 106
  SIID_DRIVEHDDVD = 132
  SIID_DRIVEBD = 133
  SIID_MEDIAHDDVDROM = 134
  SIID_MEDIAHDDVDR = 135
  SIID_MEDIAHDDVDRAM = 136
  SIID_MEDIABDROM = 137
  SIID_MEDIABDR = 138
  SIID_MEDIABDRE = 139
  SIID_CLUSTEREDDRIVE = 140
  SIID_MAX_ICONS = 175
End Enum

'Shell Structures

Private Type SHSTOCKICONINFO
  cbSize As Long
  hIcon As Long
  iSysImageIndex As Long
  iIcon As Long
  szPath(2 * MAX_PATH - 1) As Byte ' W-version ?
End Type

'uFlags - flags that specify which information is requested
Public Const SHGSI_ICON = &H100
Public Const SHGSI_LARGEICON = &H0
Public Const SHGSI_SMALLICON = &H1

'Shell Functions
Public Declare Function SHGetStockIconInfo Lib "shell32.dll" (ByVal siid As SHSTOCKICONID, _
 ByVal uFlags As Long, ByRef psii As SHSTOCKICONINFO) As Long


Public Function GetStockIcon(ByVal siid As SHSTOCKICONID, _
 Optional ByVal bLargeIcon As Boolean = False) As Long

  Dim ShIconInfo As SHSTOCKICONINFO
  Dim lRet As Long
  
  ShIconInfo.cbSize = LenB(ShIconInfo)
  
  If bLargeIcon Then
    lRet = SHGetStockIconInfo(siid, SHGSI_ICON Or SHGSI_LARGEICON, ShIconInfo)
  Else
    lRet = SHGetStockIconInfo(siid, SHGSI_ICON Or SHGSI_SMALLICON, ShIconInfo)
  End If
  
  If lRet = S_OK Then GetStockIcon = ShIconInfo.hIcon

End Function




М.б. вот это поможет
SHGSI_SHELLICONSIZE
Modifies the SHGSI_LARGEICON or SHGSI_SMALLICON values by causing the function to retrieve the Shell-sized icons rather than the sizes specified by the system metrics.
Хотя почему-то думаю что больше чем 32х32 (SHGSI_LARGEICON) не выудишь.
Я использовал только для выуживания маленьких иконок 16х16 (SHGSI_SMALLICON).
Ну и да, это не для XP.
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253226
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PantaloneДа уж. А из ресурсов системы тоже толком не вытащить, хотя размер в этом случае нормальный получается, но Windows 7 в Shell32.dll нашел кучу значков с восклицательным знаком
Вытаскивать из ресурсов проще всего программой IcoFX, последняя оф. бесплатная версия 1.6.4
В shell32.dll иконка такая есть, макс. размер/качество 48х48 - 32
Причем если хочешь без головной боли рисовать именно 48х48 и не ломать голову по каким принципам винды выбирают размер/качество, то в свой ресурс кладешь именно один размер 48х48 -32, грузишь ее через LoadImage в ориг. размере.
Код: vbnet
1.
    lngIcon = LoadImage(App.hInstance, MAKEINTRESOURCE(140), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR)


а потом без всяких опять же масштабирований рисуешь
Код: vbnet
1.
   DrawIconEx Picture1.hdc, 0, 0, lngIcon, 0, 0, 0, 0, DI_NORMAL
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253227
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий, благодарю за советы и код, может пригодится еще. Удалось найти все же где винда хранит стандартные иконки, помог Dependency Walker в момент вызова этой иконки, они лежат в c:\windows\System32\USER32.DLL, пока буду оттуда тягать, масштабируются нормально.
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253230
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77MAKEINTRESOURCE
А нет ли примера как эта штуковина объявляется? Что-то не могу найти.
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253234
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PantaloneДмитрий77MAKEINTRESOURCE
А нет ли примера как эта штуковина объявляется? Что-то не могу найти.


Код: 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.
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
 Destination As Any, Source As Any, ByVal length As Long)

Public Function LOWORD(ByVal dwValue As Long) As Long
  Call CopyMemory(LOWORD, dwValue, 2)
End Function

Public Function HIWORD(ByRef lThis As Long) As Long
  If (lThis And &H80000000) = &H80000000 Then
    HIWORD = ((lThis And &H7FFF0000) \ &H10000) Or &H8000&
  Else
    HIWORD = (lThis And &HFFFF0000) \ &H10000
  End If
End Function

Public Function MAKELONG(ByVal wLow As Long, ByVal wHi As Long) As Long
  If (wHi And &H8000&) Then
    MAKELONG = (((wHi And &H7FFF&) * 65536) Or (wLow And &HFFFF&)) Or &H80000000
  Else
    MAKELONG = LOWORD(wLow) Or (&H10000 * LOWORD(wHi))
  End If
End Function

Public Function MAKEINTRESOURCE(ByVal lId As Long) As String
  MAKEINTRESOURCE = "#" & CStr(MAKELONG(lId, 0))
End Function


Вроде ничего не потерял (чтоб не было дальнейших вопросов).

MAKEINTRESOURCE(140)
ссылается на иконку с ID=140, но 140-именно цифра, а не строка "140".
VB-шный редактор ресурсов кажется умеет только строки( чтоб делать цифры можно использовать C-шный из 6-й студии, хотя C++ 6.0 на Win7 воткнуть еще большая проблема чем VB6), причем VB6 умеет только 256 цветов.
Т.е. впихиваешь 256(или 16)-цветные дубли, компилируешь с ними exe,
потом через reshacker меняешь иконки на полноцветные (в готовом exe) через bat-файл (+скрипт)
В общем это целая кухня, если освоить, то уже проще.
В .Net этих проблем нет (правда других хватает).
...
Рейтинг: 0 / 0
Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
    #39253723
Pantalone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо большое.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как получить иконку IDI_EXCLAMATION при размере шрифтов 150%?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]