Хочу иконку на CommandButton слева от текста, а не сверху.

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Хочу иконку на CommandButton слева от текста, а не сверху.

Сообщение VDeltsov » 20.06.2007 (Ср) 11:22

В Toolbare можно с помощью TextAlignment = 1 (tbrTextAlignRight) сделать так, чтобы слева от текста была иконка, а справа от иконки - текст, например:

--------------
|[+] Новый|
--------------

где [+] - красивая иконка.

Тоже самое хочется сделать не используя Toolbar. А используя обычную кнопку CommandButton.
По умолчанию на кнопке иконка рисуется сверху посередине, а текст - снизу посередине:

--------------
|.....[+]......|
|...Новый...|
--------------


Выровнять надпись с помощью вот этого кода удается только для кнопки, у которой нет иконки (Style = Standart), а для Graphical не работает:


Код: Выделить всё
Private Declare Function GetWindowLong& Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long)
Private Declare Function SetWindowLong& Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long)
Const A_CENTER = &H300&
Const A_TOP = &H400&
Const A_TOPLEFT = &H500&
Const A_TOPRIGHT = &H600&
Const A_BOTTOM = &H800&
Const A_BOTTOMLEFT = &H900&
Const A_BOTTOMRIGHT = &HA00&
Const A_LEFT = &H100&
Const A_RIGHT = &H200&
Const GWL_STYLE& = (-16)
Private Sub Command1_Click()
Dim tmpValue&
Dim Align&
Dim ret&
'Данный пример расположит надпись на кнопке вверху кнопки
'Для того, чтобы расположить надпись в другом месте, используйте константы, начинающиеся с A_
fAlignment& = A_RIGHT
tmpValue& = GetWindowLong&(Command1.hwnd, GWL_STYLE) And Not BS_RIGHT
ret& = SetWindowLong&(Command1.hwnd, GWL_STYLE, tmpValue& Or fAlignment&)
Command1.Refresh
End Sub



Использовать Tolbar для каждой такой кнопки пока не охота по идеологическим причинам:
- это не круто
- использование Tolbar-а отличается от кнопки
- размер кнопки Tolbar-а нельзя установить самому, поэтому все нопки разного размера, если использовать свой Tolbar на каждую кнопку.
- все кнопки одинакового размера, если использовать один Tolbar на все кнопки, а это тоже выгляит ублюдочно, если на одной из кнопок 2-3 слова, а на других - по одному.

------------------------------------------------------------
Итак вопрос:
Как выровнять иконку на CommandButton слева от текста, используя API-функции, и не используя и не создавая других контролов.

------------------------------------------------------------

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 20.06.2007 (Ср) 12:42

Первое, что приходит в голову, это присобачить с помощью SetParent иконку (Image не попрет, придется PictureBox ибо у него есть .HWnd) к кнопке (CommandButton)
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Alex[fj]
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 278
Зарегистрирован: 17.02.2007 (Сб) 20:10
Откуда: Питер

Сообщение Alex[fj] » 20.06.2007 (Ср) 12:50

Ссылаясь на VB_D3D_Денис, кидаю код
Код: Выделить всё
Const DI_MASK = &H1
Const DI_IMAGE = &H2
Const DI_NORMAL = DI_MASK Or DI_IMAGE
Private Declare Function ExtractAssociatedIcon Lib "shell32.dll" Alias "ExtractAssociatedIconA" (ByVal hInst As Long, ByVal lpIconPath As String, lpiIcon As Long) As Long
Private Declare Function DrawIconEx Lib "user32" (ByVal hdc As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long
Private Declare Function DestroyIcon Lib "user32" (ByVal hIcon As Long) As Long
Private Sub Form_Paint()
        Dim mIcon As Long
    'иконка, которую рисуем
    mIcon = ExtractAssociatedIcon(App.hInstance, "C:\Autoexec.bat", 2)
    'русием иконку на форме
    DrawIconEx Me.hdc, 0, 0, mIcon, 0, 0, 0, 0, DI_NORMAL
        DestroyIcon mIcon
End Sub

Пример был - рисование иконки по форме
Должно пригодиться :)
Изображение
Стараюсь быть вполне хорошим (c) Лев Толстой

VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Сообщение VDeltsov » 20.06.2007 (Ср) 13:13

не хочется использовать дополнительные контролы.
Т.к. придется на каждой форме их обрабатывать (например, задизайблил кнопку, надо заботиться о том, чтобы иконка задизэйблилась; скрыл кнопку, надо заботиться о том, чтобы скрылась иконка; передвинул програмно кнопку, надо двигать иконку и т.д.), а это гемор.

В идеале нужно создать функцию в модуле, которую использовать по всему проекту 500 раз:

Код: Выделить всё

Public Sub CommandAlignIconLeft(aCommand as CommandButton)

End sub

Alex[fj]
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 278
Зарегистрирован: 17.02.2007 (Сб) 20:10
Откуда: Питер

Сообщение Alex[fj] » 20.06.2007 (Ср) 13:26

VDeltsov, ну тогда создай свой контрол, который тебя удволетворит:
основная чать, а на ней слева маленький региончик для картинки :yes:
Изображение
Стараюсь быть вполне хорошим (c) Лев Толстой

VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Сообщение VDeltsov » 20.06.2007 (Ср) 13:41

Alex[fj] писал(а):VDeltsov, ну тогда создай свой контрол, который тебя удволетворит:
основная чать, а на ней слева маленький региончик для картинки :yes:


В том-то и дело, что свой контрол не хочу делать.
Был как-то случай, у нас чуваки делали свой combobox, у которого ширина выпадающего списка была больше, чем сам контрол в свернутом состоянии и у котого можно было регулировать кол-во видимых элементов в списке. Но поскольку это делали чуваки сами, то он иногда проглючивал.
А потом через 3 года я нашел как и то, и другое сделать из обычного combobox-а двумя простыми API-функциями:

Код: Выделить всё

Option Explicit

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As Rect) As Long

Private Const SWP_NOMOVE = &H2
Private Const CB_SETDROPPEDWIDTH = &H160
Private Const CB_GETITEMHEIGHT = &H154

Private Type Rect
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

'Установить кол-во видимых элементов в списке (не менее 8)
Public Sub ComboSetDropdownCount(aCombo As ComboBox, iDropdownCount As Long)
    Dim ComboRect As Rect 'Структура с размерами комбобокса
    Dim ItemHeight As Long 'Высота одной строки

    GetWindowRect aCombo.hwnd, ComboRect
    ItemHeight = SendMessage(aCombo.hwnd, CB_GETITEMHEIGHT, 0, 0)
   
    SetWindowPos aCombo.hwnd, 0, 0, 0, (ComboRect.Right - ComboRect.Left), ItemHeight * (iDropdownCount + 2), SWP_NOMOVE
End Sub


'Установить ширину выпадающего списка в ПИКСЕЛЯХ
Public Sub ComboSetDroppedWidth(aCombo As ComboBox, iDroppedWidth As Long)
    SendMessage aCombo.hwnd, CB_SETDROPPEDWIDTH, ByVal iDroppedWidth, 0
End Sub


Private Sub Form_Load()
    Dim i As Long

    For i = 1 To 100
        Me.Combo1.AddItem i
    Next

    ComboSetDroppedWidth Me.Combo1, 300

    ComboSetDropdownCount Me.Combo1, 45
End Sub



Надеюсь, что и тут уже решение есть...
А делать свой кнотрол не хочу, т.к. его придется регистрировать у клиентов.
Плюс по проекту уже куча кнопок (которым хочу для презентабельности припрепить иконки). А пихать туда свой контрол - негуманно.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 20.06.2007 (Ср) 13:45

UserControl не надо регистрировать.
А замену можно сделать автоматически.
Lasciate ogni speranza, voi ch'entrate.

VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Сообщение VDeltsov » 20.06.2007 (Ср) 13:51

alibek писал(а):UserControl не надо регистрировать.
А замену можно сделать автоматически.


Все равно НЕ ХОЧУ СОЗДАВАТЬ СВОЙ КОНТРОЛ!

Попробуйте внимательно прочитать вопрос:
Как выровнять иконку на CommandButton слева от текста, используя API-функции, и не используя и не создавая других контролов?

Если не знаете ответа на этот [вполне конкретный] вопрос, то просто не пишите.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 20.06.2007 (Ср) 14:20

WM_OWNERDRAW.
Дальше ты несомненно разберешься.
Lasciate ogni speranza, voi ch'entrate.

VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Сообщение VDeltsov » 20.06.2007 (Ср) 14:55

alibek писал(а):WM_OWNERDRAW.
Дальше ты несомненно разберешься.


Если честно, не вижу как с помощью этого малой кровью решить задачу.
Может подскажешь?

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 20.06.2007 (Ср) 15:57

И даже в поиске не видишь?
Нужно сабклассить и самостоятельно отрисовывать кнопку.
Лучший способ понять что-то самому — объяснить это другому.

VDeltsov
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 23
Зарегистрирован: 30.07.2005 (Сб) 14:42
Откуда: Moscow

Сообщение VDeltsov » 21.06.2007 (Чт) 16:34

Antonariy писал(а):И даже в поиске не видишь?
Нужно сабклассить и самостоятельно отрисовывать кнопку.


Извиняюсь, но я в сабклассинге полный ноль (может кто расскажет как прорисовать иконку на кпопке в глобальной функции, у которой два параметра: кпонка и название иконки из ListImage, используя только стандартные функции, работающие в идеале на чистой машине под win98).

Но, на сколько я понимаю, при сабклассинге непрерывно будет вызываться функция перерисовки, и отладка основного кода приложения будет сильно затруднена, или не так?


Может у кого-нибудь все же есть стабильно работающий вариант такой фичи, не требущий много крови?
Вроде фича-то весьма полезная для презентабелности проекта.
Последний раз редактировалось VDeltsov 17.08.2007 (Пт) 18:20, всего редактировалось 2 раз(а).

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.06.2007 (Чт) 16:42

Самый простой способ тебе уже сказали, это UserControl.
Сабклассинг в данном случае не так уж и сложен, обработка везде будет однотипной. Но смысла в нем мало.
Lasciate ogni speranza, voi ch'entrate.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 87

    TopList