Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Служба Рассылок Городского Кота


Служба Рассылок Городского Кота
Visual Basic - Трюки и Хитрости, советы и ответы на вопросы.
Здравствуйте, уважаемые читатели!

Я слегка ошалел, когда увидел, какими темпами растет число подписчков этой
рассылки. Видимо VB становится достаточно популярным и в России. Что-же,
надеюсь эта рассылка и сайт "Visual Basic на русском" http://vbrussian.com
помогут популяризаци этого мощного и доступного пониманию языка.

Сегодняшний выпуск посвящен разностям, а точнее полезным хитростям, которые
могут вам пригодится в нелегкой програмистской жизни.

Ведет этот выпуск Константин Рудой ( mailto:kosty@vbrussian.com )
==================================================================

Все знают, что можно загрузить контрол используя стейтмент Load. Но для
этого нужно иметь такой же контрол на форме, да к тому же он должен быть
инициализирован как массив. А как быть, если на форму не хочется класть
ничего лишнего? Оказывается нет ничего сложного. Думаю, что ни для кого не
секрет, что у формы есть коллекция Controlls?

Так вот, почему бы и не воспользоваться методом Add коллекции.
(VB6)
Этот метод имеет 3 параметра :
1 - строковый идентификатор контролла (например "VB.CommandButton")
2 - строка - имя контролла
3 - необязательный параметр - контейнер в который этот контролл будет
положен

Допустим мы хотим создать кнопку на форме. что же для этого нужно сделать?
Всего несколько строк:

В Genegal - Declaration:

Dim WithEvents cmdDynamicButton As Button


В том месте кода где мы хотим создать новую кнопку (например на Form_Load):

Me.Controls.Add "VB.CommandButton", "NewButton"
Set cmdDynamicButton = Me.Controls("NewButton")

Просто? Конечно.
Но у вас может возникнуть законный вопрос, а как же обрабатывать события от
такого контролла? Но ведь для этого мы м опичывали переменную
cmdDynamicButton как WithEvents.

Теперь добавтье к коду следующие строки и наслаждайтесь...

Private Sub cmdDynamicButton_Click()
    MsgBox "This is a dynamically added button"
End Sub

И еще пара замечаний напоследок:
1) Для того чтобы удалить такой контролл мспользуйте метод Remove  всe: той
же коллекции
2) Для добавления контролла на который у вас нет ссылки в проекте (его нет
в тулбоксе) его лицензию еще нужно добавить в коллекцию Licenses.
подробности можно прочесть в MSDN.


======================================================================

Жизнь течет, а нам хочется всe: большего и большего...

Вам никогда не хотелось сделать размер вашего листбокса пропорционально
количеству строк? Нет? А мне вот захотелось...
И для этого окозалось достаточно всего трех API-функций:
GetTextMetrics, CetWindowRect и GetClientRect.

Private Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA"
(ByVal hdc As Long, lpMetrics As TEXTMETRIC) As Long

Private Type TEXTMETRIC
        tmHeight As Long
        tmAscent As Long
        tmDescent As Long
        tmInternalLeading As Long
        tmExternalLeading As Long
        tmAveCharWidth As Long
        tmMaxCharWidth As Long
        tmWeight As Long
        tmOverhang As Long
        tmDigitizedAspectX As Long
        tmDigitizedAspectY As Long
        tmFirstChar As Byte
        tmLastChar As Byte
        tmDefaultChar As Byte
        tmBreakChar As Byte
        tmItalic As Byte
        tmUnderlined As Byte
        tmStruckOut As Byte
        tmPitchAndFamily As Byte
        tmCharSet As Byte
End Type

Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long,
lpRect As RECT) As Long

Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long,
lpRect As RECT) As Long

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

Но не всe: так просто... Всe: дело в том, что для GetTextMetrics в качестве
первого параметра необходимо задать hDC. А для этого нужен контролл,
который умеет его возвращать или пытаться его добыть какими-то иными
средствами, что гораздо сложнее.

Итак. У нас на форме есть листбокс List1 (хотя это может быть и любой иной
контролл) и пикчербокс Picture1, который мы или создаем динмически в
Form_Load (см. Как динамически загрудить контролл) или просто кладем его на
форму. Желательно чтоб он был спрятан, т.к. в Form_Load должна быть
следующая строка:

    Set Picture1.Font = List1.Font

Ну и функция, которая возвращает размер контрола по количеству строк:

' hwnd - хэндл контролла (в нашем случае - List1.Hwnd
' Count - количество строк

Private Function GetHeightByLinesCount(hwnd As Long, Count As Integer) As
Long
    Dim tm As TEXTMETRIC
    Dim rc As RECT
    Dim winrc As RECT

    ' Получаем размер окна
    GetWindowRect hwnd, winrc
    ' Получаем размер клиетской области окна
    GetClientRect hwnd, rc
    ' Получаем параметры шрифта из Picture1
    GetTextMetrics pic.hdc, tm

    ' winrc.Bottom - winrc.Top - rc.Bottom + rc.Top - это размер бордера
контролла
    ' в пикселах
    ' tm.tmHeight - высота строки тоже в пикселах
    ' поскольку всe: в пикселах, то переводим в Твипсы
    GetHeightByLinesCount = (tm.tmHeight  Count + winrc.Bottom - winrc.Top
- rc.Bottom + rc.Top)  Screen.TwipsPerPixelY
End Function

Ну теперь уж точно всe:. Можно пользоваться и наслаждаться...
Констстантин Рудой
======================================================================



ДА, напоследок: Cвежая информация о том, что же будет завтра, что нового
предпологается в  версии VB7 - ждет вас по адресу:
http://vbrussian.com/vb7_2.html
Успехов в программировании!

Борис Рудой

Автор сайта - Visual Basic на русском



http://subscribe.ru/
E-mail: ask@subscribe.ru

В избранное