powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
5 сообщений из 5, страница 1 из 1
C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
    #38298552
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Создать создал.
Но поведение не совсем правильное.
Т.е. он должен быть подчеркнут когда мышка по нему елозит, а у меня он подчеркнут ВСЕГДА (с курсором руки все в порядке).
Вод код:
Код: 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.
Option Explicit

Private Const WS_CHILD                   As Long = &H40000000
Private Const WS_VISIBLE                 As Long = &H10000000
Private Const WS_TABSTOP        As Long = &H10000

Private Const WC_LINK = "SysLink"

Private Declare Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExA" _
 (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, _
 ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
 ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Any) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
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 Const WM_SETFONT = &H30

Public Function CreateTheSysLink(hWndParent As Long, Left As Long, _
  Top As Long, Width As Long, Height As Long, the_text As String) As Long

    Dim rcClient As RECT
     
    GetClientRect hWndParent, rcClient

    Dim SysLinkStyle As Long
 
    SysLinkStyle = WS_CHILD Or WS_VISIBLE Or WS_TABSTOP

    CreateTheSysLink = CreateWindowEx(0, _
      WC_LINK, _
      the_text, _
      SysLinkStyle, _
      rcClient.Left + Left, _
      rcClient.Top + Top, _
      Width, _
      Height, _
      hWndParent, _
      0&, _
      App.hInstance, _
      0&)
      
  Dim fnt As IFont
  If IsWinVista Then
    Set fnt = Form1.LabelFont.Font
  Else
    Set fnt = Form1.Font
  End If
  SendMessage CreateTheSysLink, WM_SETFONT, fnt.hFont, ByVal 0
  Set fnt = Nothing
End Function


Сразу оговорюсь, что код работает только под манифестом, это оговорено в msdn.
Как лечить подчеркивание?

В принципе подобное реализуется через обычную VB6-label. Но то чего хочу все равно не получится, тк по mouse_move я могу "подчеркнуть текст", но на снять подчеркивание события нет, если только не лепить детский сад по mouse_move соседних элементов. Ну плюс focus rectangle у label нету.
...
Рейтинг: 0 / 0
C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
    #38299107
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чего-то ничего не получается

Поигрался с LM_SETITEM

Код: 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.
Private Const L_MAX_URL_LENGTH = 2048 + 32 + 3
Private Const MAX_LINKID_TEXT = 48

Public Type tagLITEM
  mask As Long
  iLink As Long
  state As Long
  stateMask As Long
  szID As String * MAX_LINKID_TEXT
  szUrl As String * L_MAX_URL_LENGTH
End Type

Public Const LIF_ITEMINDEX = &H1
Public Const LIF_STATE = &H2
Public Const LIF_ITEMID = &H4
Public Const LIF_URL = &H8
  
Public Const LIS_FOCUSED = &H1
Public Const LIS_ENABLED = &H2
Public Const LIS_VISITED = &H4
Public Const LIS_HOTTRACK = &H8
Public Const LIS_DEFAULTCOLORS = &H10

Public Const WM_USER = &H400
Public Const LM_SETITEM = (WM_USER + &H302)
Public Const LM_GETITEM = (WM_USER + &H303)



Вот так можно сделать enable=false
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private Sub DoDisable()
  Dim tLitem As tagLITEM
  With tLitem
    .iLink = 0
    .mask = LIF_ITEMINDEX Or LIF_STATE
    .state = 0 ' =LIS_ENABLED чтоб восстановить
    .stateMask = LIS_ENABLED 
  End With
  MsgBox SendMessage(hSysLink, LM_SETITEM, 0, tLitem)
End Sub



На вистах работает еще
LIS_HOTTRACK -приобретает светло-голубой цвет
LIS_DEFAULTCOLORS -приобретает черный цвет

Больше ничего не выжал.
Или это не задокументировано в MSDN, или это нормально не делается. Странно.
В .net на тему подчеркивания есть Hover Underline.
Но при том сразу обратил внимание на то, что .Net контрол не показывает фокус при нажатии мышкой (нестандарт).
...
Рейтинг: 0 / 0
C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
    #38299496
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А все-таки я это сделал.

Надо понять состояние, когда мышь пришла в SysLink и что несколько сложнее что она оттуда ушла. Состояние что мышь в SysLink определяем константой State_HotTrack
1. Сабклассим SysLink и ловим первый WM_MOUSEMOVE
В нем:
1) фиксируем состояние "мышь в SysLink" (State_HotTrack = True)
2) заказываем событие WM_MOUSELEAVE (само не вызовется) через вызов TrackMouseEvent+TME_LEAVE
3) меняем состояние SysLink на LIS_HOTTRACK (ссылка подсвечивается), либо на любое другое (например можно использовать LIS_FOCUSED) -тогда цвет ссылки не меняется
4) Пункт 3 что существенно вызывает NM_CUSTOMDRAW , которое следит за "подчеркиванием", поэтому хоть что-то (пусть незаметное) там надо вызвать.

2. При получении WM_MOUSELEAVE (оно гарантированно вызовется в силу 1.2)
1) фиксируем состояние "мышь ушла" (State_HotTrack = False)
2) снимаем флаг LIS_HOTTRACK (убираем подсвечивание), либо другое установленный (например LIS_FOCUSED если цвет ссылки не менялся)
3)Пункт 2 что опять существенно вызывает NM_CUSTOMDRAW , которое следит за "подчеркиванием".

Код: 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.
Public Function NewMyLinkWindowProc( _
 ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
  Dim tLitem As tagLITEM
 
  Select Case Msg
    Case WM_MOUSEMOVE
       If State_HotTrack = False Then
        State_HotTrack = True
        TrackControlLeave Form1.hLinkTest
        SetLinkHottrack Form1.hLinkTest, IIf(ThemesEnabled(Form1.hLinkTest), LIS_HOTTRACK, LIS_FOCUSED), True
      End If
    Case WM_MOUSELEAVE
      State_HotTrack = False
      SetLinkHottrack Form1.hLinkTest, IIf(ThemesEnabled(Form1.hLinkTest), LIS_HOTTRACK, LIS_FOCUSED), False
    Case Else
  End Select
  
  NewMyLinkWindowProc = CallWindowProc( _
   OldMyLinkWindowProc, hwnd, Msg, wParam, _
   lParam)
End Function

Private Sub TrackControlLeave(hwnd As Long)
  Dim ET As TRACKMOUSEEVENTTYPE
  'initialize structure
  With ET
    .cbSize = Len(ET)
    .hwndTrack = hwnd
    .dwFlags = TME_LEAVE
  End With
  TrackMouseEvent ET
End Sub

Private Sub SetLinkHottrack(hSysLink As Long, LIS_CONST As LIS_constants, track As Boolean)
  Dim tLitem As tagLITEM
  With tLitem
    .iLink = 0
    .mask = LIF_ITEMINDEX Or LIF_STATE
    .state = IIf(track, LIS_CONST, 0)
    .stateMask = LIS_CONST
  End With
  SendMessage hSysLink, LM_SETITEM, 0, tLitem
End Sub

Public Enum LIS_constants
  LIS_FOCUSED = &H1
  LIS_ENABLED = &H2
  LIS_VISITED = &H4
  LIS_HOTTRACK = &H8
  LIS_DEFAULTCOLORS = &H10
End Enum



Ну, а задача CustomDraw -
вернуть "шрифт с подчеркиванием" когда State_HotTrack = True
либо
вернуть "шрифт без подчеркивания" когда State_HotTrack = False

Код: 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.
        Case NM_CUSTOMDRAW
          If uNMHDR.hwndFrom = Form1.hLinkTest Then
            Static lvcd As NMCUSTOMDRAW
            CopyMemory lvcd, ByVal lParam, Len(lvcd)   ' every structs' member is a Long
            Select Case lvcd.dwDrawStage
              ' ====================================================
              Case CDDS_PREPAINT
                NewFormMeWindowProc = CDRF_NOTIFYITEMDRAW
                Exit Function
                ' ====================================================
              Case CDDS_ITEMPREPAINT
                 
                If State_HotTrack Then
                  SelectObject lvcd.hdc, fnt_Underlined.hFont
                Else
                  SelectObject lvcd.hdc, fnt_Normal.hFont
                End If
                NewFormMeWindowProc = CDRF_NEWFONT
               Exit Function
              Case Else
            End Select
          End If
        Case Else
      End Select



Но - это работает только на Вистообразных.
На XP не поддерживается LIS_HOTTRACK и ни одно из LIS_ не вызывает CustomDraw, т.е. нету ввода для управления подчеркиванием.
Еще на классике в Vista лучше использовать LIS_FOCUSED -т.е. цвет не меняется, а CustomDraw генерируется - цвет выделения там фиговый какой-то.
...
Рейтинг: 0 / 0
C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
    #38299506
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно вот этого добивался.
Для XP (и классика и XP тема) думаю сойдет стандартное поведение.
...
Рейтинг: 0 / 0
C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
    #38299639
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вот этого понять не могу:
Дмитрий77На XP ... ни одно из LIS_ не вызывает CustomDraw, т.е. нету ввода для управления подчеркиванием.
Если глядеть в ControlSpy, то NM_CustomDraw от SysLink там генерируется прекрасно на том же XP, а у меня в проге нет. Почему?
По крайне мере при нажатии на него он же перерисовывается.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / C SysLink контролом кто сталкивался? Как сделать чтоб ссылка не всегда была подчеркнута?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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