Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать событие Handle на "все элементы одного типа" / 4 сообщений из 4, страница 1 из 1
15.09.2013, 04:06
    #38396918
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как сделать событие Handle на "все элементы одного типа"
Например есть MainMenu1
У него есть итемы: menu_FileNew, menu_FileEdit, menu_FileDelete и так далее (существенно)

Я могу делать так:
Код: vbnet
1.
2.
3.
4.
5.
  Private Sub menu_FileNew_DrawItem(ByVal sender As Object,
   ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles menu_FileNew.DrawItem
  Private Sub menu_FileNew_DrawItem(ByVal sender As Object,
   ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles menu_FileEdit.DrawItem
...


Я могу делать так:
Код: vbnet
1.
2.
3.
4.
  Private Sub AnyMenuItem_DrawItem(ByVal sender As Object,
   ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles menu_FileNew.DrawItem,
   menu_FileEdit.DrawItem,
   ...

, где AnyMenuItem_DrawItem -название ф-ции обработчика, при этом должен тупо и явно перечислять Handles

Я хочу записать:
Код: vbnet
1.
2.
  Private Sub AnyMenuItem_DrawItem(ByVal sender As Object,
   ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles <Любой элемент вида MenuItem>.DrawItem


Как? Т.е. у меня 20,30,40 пунктов меню, я могу какие-то добавлять, какие-то удалять, но я хочу для любого элемента вида MenuItem обрабатывать .DrawItem в этой ф-ции.

Я видел про AddHandler, но опять же, я должен ручками делать Add для каждого пункта, или хотя бы что-то типа
For Each item in items.
Меня это не очень устраивает.

Мне надо что-то типа
Код: vbnet
1.
Handles System.Windows.Forms.MenuItem.DrawItem


Подобную задачу когда-то решал:
8494847
Не могу сказать что очень удачно.
...
Рейтинг: 0 / 0
15.09.2013, 10:57
    #38396948
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как сделать событие Handle на "все элементы одного типа"
Код: vbnet
1.
Handles menu_FileNew.DrawItem, menu_FileEdit.DrawItem, ...
...
Рейтинг: 0 / 0
15.09.2013, 17:47
    #38397082
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как сделать событие Handle на "все элементы одного типа"
Antonariy
Код: vbnet
1.
Handles menu_FileNew.DrawItem, menu_FileEdit.DrawItem, ...


Ну и?
Ты предлагаешь тупо и поименно перечислять все "40 элементов" через запятую, я на этот вариант указал (второй сверху) и сказал что меня не устраивает.

Тогда уж мой третий вариант:
Код: 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.
  Private Sub Form1_Load(ByVal sender As System.Object,
                         ByVal e As System.EventArgs) Handles MyBase.Load
...
    'menu
    For Each menu_item As MenuItem In MainMenu1.MenuItems
      If (menu_item.Text = "&File") Or (menu_item.Text = "&Help") Then
        For Each menu_subitem As MenuItem In menu_item.MenuItems
          AddHandler menu_subitem.DrawItem, AddressOf DrawMenuItem
        Next
      End If
    Next
...

  Private Sub DrawMenuItem(ByVal sender As Object,
   ByVal e As System.Windows.Forms.DrawItemEventArgs)
    'TextBox1.Text &= vbCrLf & "menu_FileNew_DrawItem"
    Dim item_disabled As Boolean = Not CType(sender, MenuItem).Enabled
    Dim item_text As String = CType(sender, MenuItem).Text
    Dim item_icon As Icon = Nothing
    Select Case item_text
      Case "&New..."
        item_icon = IIf(item_disabled, My.Resources.CONTACT_NEWBW,
         My.Resources.CONTACT_NEW)
      Case "&Edit..."
        item_icon = IIf(item_disabled, My.Resources.CONTACT_EDITBW,
         My.Resources.CONTACT_EDIT)
...
      Case "&Help Topics"
        item_icon = IIf(item_disabled, My.Resources.HELPBW,
         My.Resources.HELP)
      Case Else
    End Select
    If IsNothing(item_icon) = False Then
      e.Graphics.DrawIcon(item_icon, e.Bounds.Left - 16,
       e.Bounds.Top + (e.Bounds.Bottom - e.Bounds.Top - 16) / 2)
    End If
  End Sub



Но ты знаешь, проще здесь API везде оставить.
Потому как все что сделано в VB6 здесь работает,
все вот эти темы:
А вообще иконки в VB6 меню тяжело добавить?
Как заменить "вдавленный стиль" на "серый" (в меню)

Вот как на .NET сделать это:
Код: vbnet
1.
2.
3.
4.
          'здесь устанавливаем "серый стиль" на классике (код ниже позволяет поменять цвет menu item на любой!!!)
          If App_ThemesEnabled() = False Then
            If item_disabled Then SetTextColor(dm.hdc, GetSysColor(COLOR_GRAYTEXT))
          End If


Издеваться над нетовским GetDC?

Или вот это (Alpha-Blended bitmaps -на Вистах картинки не через DrawItem делаются):
Я попробовал тупо взять .ToBitmap(.net ресурс -иконка) вместо HBITMAP_fromICON
Догадываешься какая там мазня получилась?

Код: 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.
      Case WM_INITMENUPOPUP 'menu
...
                  SetMenuItemBitmaps(m.WParam, 0, MF_BYPOSITION, h_MENU_Bitmap(0), h_MENU_Bitmap_BW(0)) '&New...

  Private Sub InitMenuImages()
    'ресурсы 16х16
    '&File/Edit
    'CONTACT_NEW (0)
    'CONTACT_EDIT (1)
...

     'http://msdn.microsoft.com/en-us/library/bb757020.aspx
    'but Windows Vista® uses alpha-blended bitmaps instead
    'Набор Bitmap для меню Form1 Виста
    '&File/Edit
    h_MENU_Bitmap(0) = HBITMAP_fromICON(My.Resources.CONTACT_NEW.Handle) 'CONTACT_NEW=0
    h_MENU_Bitmap(1) = HBITMAP_fromICON(My.Resources.CONTACT_EDIT.Handle) 'CONTACT_EDIT=1
...
  End Sub

  Public Function HBITMAP_fromICON(ByVal lngIcon As IntPtr) As IntPtr
    'возвращает alpha-blended bitmap соотв. иконке в ресурсах - для меню на Vista и выше
    Dim hdc As IntPtr
    Dim hMemDC As IntPtr
    Dim hMemBmp As IntPtr
    Dim hResultBmp As IntPtr
    Dim hOrgBMP As IntPtr
    Dim bmiDst As BITMAPINFO2
    Dim pBits As Integer

    hdc = GetDC(0)
    hMemDC = CreateCompatibleDC(hdc)

    With bmiDst.bmiHeader
      .biSize = Marshal.SizeOf(bmiDst.bmiHeader)
      .biWidth = 16
      .biHeight = 16
      .biPlanes = 1
      .biBitCount = 32
      .biCompression = BI_RGB
    End With
    hMemBmp = CreateDIBSection(0, bmiDst, DIB_RGB_COLORS, pBits, 0, 0)

    'hMemBmp = CreateCompatibleBitmap(hdc, 16, 16)
    hResultBmp = 0
    hOrgBMP = SelectObject(hMemDC, hMemBmp)
    DrawIconEx(hMemDC, 0, 0, lngIcon, 16, 16, 0, 0, DI_NORMAL)
    hResultBmp = hMemBmp
    hMemBmp = 0
    SelectObject(hMemDC, hOrgBMP)
    DeleteDC(hMemDC)
    ReleaseDC(0, hdc)
    'DestroyIcon(lngIcon)
    HBITMAP_fromICON = hResultBmp
  End Function



По хорошему конечно ToolStrip,
но он гад не поддерживает системные стили (на Вистах - даже эмуляции нет).
А ты ж меня знаешь, я люблю все делать в стиле системы.
...
Рейтинг: 0 / 0
15.09.2013, 22:52
    #38397167
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как сделать событие Handle на "все элементы одного типа"
Дмитрий77Ты предлагаешь тупо и поименно перечислять все "40 элементов" через запятую, я на этот вариант указал (второй сверху) и сказал что меня не устраивает.Извиняюсь, не заметил.
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать событие Handle на "все элементы одного типа" / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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