powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Взаимное положение ListView/Treeview
25 сообщений из 59, страница 1 из 3
Взаимное положение ListView/Treeview
    #36638149
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. задача:
1) Есть form
2) Слева Treeview
3) Справа Listview
4) Между ними перемычка

Надо, чтоб если тянешь за перемычку вправо-влево то Treeview-width увеличивается, Listview-width соотв. уменьшается (толщина перемычки соотв. постоянна, т.е двигаем типа границу между ними).
В общем, не суть это могут быть 2 текстбокса.

При этом надо понимать что ширина Treeview не может быть меньше какого-то MIN разумного значения.
То же про Listview.

В принципе, есть у меня готовый vb-based код.
1) mouse_down проверяет не на перемычке ли
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Xabc = X
    Yabc = Y
    If (Button =  1 ) And (X > TreeView1.Left + TreeView1.Width) And (X < ListView1( 0 ).Left) _
      And (Y > ListView1( 0 ).Top) And (Y < ListView1( 0 ).Top + ListView1( 0 ).Height) Then
        Screen.MouseIcon = PictureMIcon.Picture
        Screen.MousePointer = vbCustom 'vbSizeWE
        ResizeWindows = True
        DragStartX = X
...
2) mouse_move соотв. двигает перемычку, если ResizeWindows = True
Код: plaintext
1.
2.
3.
   If ResizeWindows Then
        TreeView1.Width = TreeWidth + (X - DragStartX)
...
        ListView1( 0 ).Move TreeView1.Left + TreeView1.Width +  30 , ListView1( 0 ).Top, ListWidth - (X - DragStartX), ListView1( 0 ).Height

Не суть. Суть в том что приведенные методы имеют недостатки:
1) относит. тяжело попасть по перемычке
2) возникают эффекты "мультипликации" при применении минимальных ширин. По сути возврат назад по факту проскока предельного значения.

Т.е. нужен мне какой то достойный пример. Подозреваю что это будет Subclassing.
Поискать попробовал, но по словам Listview/Treeview сложновато искать.

Для формы кстати аналогичный вопрос себе поставил, но там вроде все решаемо:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Public Function NewWindowProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
' Size bounds in pixels.
Const MIN_WIDTH =  200 
Const MAX_WIDTH =  500 
Const MIN_HEIGHT =  100 
Const MAX_HEIGHT =  300 

    ' Keep the dimensions in bounds.
    If msg = WM_WINDOWPOSCHANGING Then
        If lParam.cx < MIN_WIDTH Then lParam.cx = MIN_WIDTH
        If lParam.cx > MAX_WIDTH Then lParam.cx = MAX_WIDTH
        If lParam.cy < MIN_HEIGHT Then lParam.cy = MIN_HEIGHT
        If lParam.cy > MAX_HEIGHT Then lParam.cy = MAX_HEIGHT
    End If
    
    ' Continue normal processing. VERY IMPORTANT!
    NewWindowProc = CallWindowProc( _
        OldWindowProc, hwnd, msg, wParam, _
        lParam)
End Function

А с взаимным положением что-то нет идей. Я еще обратил внимание, что многие проги при mouse_down рисуют эдакую штрих/планку, кот. двигать и непрерывной перерисовки не производится.
Нужно что-то сделать, чтоб было "культурно"...
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36638338
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Измини, за сабклассинг тебе ничего не скажу, но не очень понял с классическими недостатками.

Дмитрий77
1) относит. тяжело попасть по перемычке

А почему? Чем это сложнее, чем попасть в любой другой объект?
Кроме того, надо просто разместить там какой-нить подходящий объект без границ и сделать ему MouseIcon в виде стрелочек, здорово облегчит юзеру жизнь. Да и перехватывать MouseDown можно не у формы будет , а у этого объекта и не париться с координатами.

Дмитрий772) возникают эффекты "мультипликации" при применении минимальных ширин. По сути возврат назад по факту проскока предельного значения.

Тоже не очень понял. По идее просто запрещаешь двигать перемычку дальше определенных значений и она встает как вкопанная, я как-то делал что-то подобное, но никаких артефактов не наблюдал...
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36638750
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36639071
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

спасибо, выглядит достойно, думаю то что хотел, надо изучить.

Вот кстати моя сборная солянка чем пользуюсь(сделал тест на скорую руку из чужого примера с Form_resize через API):
Скачать
Солянка глючит напр. при резком сдвиге перемычки влево-вправо за пределы формы, в большом приложении я как-то с этим борюсь(надо копать собственные коды чтоб это понять), но все равно это извращенство и не дело.
И попасть по вашей перемычке сильно проще чем по моей.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36642821
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,
код ваш очень неплохой, сейчас тестирую его.

Но есть глюк на Висте (именно на Висте при применениии Виста-темы). Картинка разделителя когда двигаем ее сильно мигает (мерцает, дрожит), нельзя это чем-нибудь отрегулировать?
Я попытался, но пока не понял в чем дело.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36643190
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покопавшись в интернете, я понял что проблема в том, что Виста не так отрисовывает через GDI. Именно поэтому для ListView и Treeview категорическое требование: применять DoubleBuffer.
Применительно к данному примеру имеем отрисовку Splitter с задержкой
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Private Sub pDrawSplitter()
Dim lhDC As Long
Dim hOldBrush As Long
   lhDC = CreateDCAsNull("DISPLAY", ByVal  0 &, ByVal  0 &, ByVal  0 &)
   hOldBrush = SelectObject(lhDC, m_hBrush)
   PatBlt lhDC, m_tSplitR.Left, m_tSplitR.Top, m_tSplitR.Right - m_tSplitR.Left, m_tSplitR.Bottom - m_tSplitR.Top, PATINVERT  'DSTINVERT
   SelectObject lhDC, hOldBrush
   DeleteDC lhDC
End Sub
Отсюда эффект мерцания.
Виновата конкретно функция
Код: plaintext
   PatBlt lhDC, m_tSplitR.Left, m_tSplitR.Top, m_tSplitR.Right - m_tSplitR.Left, m_tSplitR.Bottom - m_tSplitR.Top, PATINVERT  'DSTINVERT

Решения два:
1) (не хотелось бы, не солидно)Назначить на Висте непрерывную перерисовку, т.е. линия вообще не применяется
Код: plaintext
m_cSplitMain.FullDrag = True

2) Рисовать линию другими методами, т.е. не использовать PatBlt

Вопрос:
Как по-другому рисовать Splitter? Желательно PATINVERT(шахматно-штрихованная линия) а не DSTINVERT (черная линия).
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36644497
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий771) (не хотелось бы, не солидно)Назначить на Висте непрерывную перерисовку, т.е. линия вообще не применяется
Код: plaintext
m_cSplitMain.FullDrag = True

Это в данном случае не вариант. Проще забить на мерцалку, чем бороться с веером перерисовок (веер поверх Treeview на Висте самоустранится лишь через 1-2 сек, и это при влюченном dowblebuffer для treeview) , да и других негативов при непрер. перерисовке много.
Линию бы по-другому нарисовать.
Понятно, что драйвер видеокарты, но не хотелось бы таких hardware-зависимостей...
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36653892
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

1) Чисто из любопытства - примерчики из приложенного архива под Вистой те же проблемы испытывают?
2) IMHO, разделитель должен себя вести в соответствии с общесистемными установками. Если уж пользователь поставил галку "Show window contents while dragging", пусть сам и смотрит на слайд-шоу.
3) По-другому рисовать? Просто идея - а если взять в качестве разделителя полупрозрачное окно, скажем? Или накладывать сверху на главное окно полупрозрачное окно, на котором будет отображаться примерный новый внешний вид главного окна?
4) Вроде в семёрке ускорение двумерной графики снова поддерживается (с какими-то оговорками). Может, не стоит тратить силы на Висту?
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654019
Фотография aduka05adm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,
в том примере что вы дали , получается в коде ничего менять не надо ,
просто надо расположить свои объекты на picSplitMain и все ,а он сам поймет что с ними делать?
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654146
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктДмитрий77,

1) Чисто из любопытства - примерчики из приложенного архива под Вистой те же проблемы испытывают?
...
4) Вроде в семёрке ускорение двумерной графики снова поддерживается (с какими-то оговорками). Может, не стоит тратить силы на Висту?

Гы-... А Ваши примеры на Висте хорошо работают,однако. Палка не глючит, не мерцает.

aduka05admДмитрий77,
в том примере что вы дали , получается в коде ничего менять не надо ,
просто надо расположить свои объекты на picSplitMain и все ,а он сам поймет что с ними делать?
Который Antonariy дал, Вы хотели сказать.
Это вопрос? Если вопрос то да, так и есть, он сам все понимает.

Бенедикт, честно хотелось бы модифицировать этот пример (Antonariy), чтоб палка рисовалась как у Вас. Зря чтоль силы потратил на осознавание-внедрение....
Что сделать то надо? А то у Вас в архиве только exe-шники.

А по поводу Win7, это пускай дочка моя пока осваивает, Папочка пока до таких к-крутых систем еще не дорос.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654193
Фотография aduka05adm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,
спасибо )
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654291
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

При беглом сравнении, отличие в отрисовке между кодом, приведённым Antonariy-ем ( EasySplitter ) и примером ViewEx в том, что MFC-шная реализация (класс CSplitterWnd, см. WINSPLIT.CPP, если есть исходники MFC) 1) рисует на DC окна, а не экрана, 2) на время таскания перемычки снимает стиль окна WS_CLIPCHILDREN, чтобы рисовать поверх всех дочерних окон. Хм, вроде бы немного (а может, я чего упустил), а сказывается.

Что делать? Мне - дойти до работы и выслать VB-шные исходники от второго примера, Вам - разобраться в них, и слить с cSplitter, чтобы получился нормальный класс в итоге.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654380
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктДмитрий77,
2) на время таскания перемычки снимает стиль окна WS_CLIPCHILDREN, чтобы рисовать поверх всех дочерних окон....

Что делать? Мне - дойти до работы и выслать VB-шные исходники от второго примера, Вам - разобраться в них, и слить с cSplitter, чтобы получился нормальный класс в итоге.

Спасибо, буду ждать пока дойдете до работы...

P.S. Мо быть мне кто объяснит все же: здесь все очень лихо прикладывают zip-ы, rar-ы а я туплю и не знаю как это сделать и вынужден класть файлы на, скажем так, не совсем свой ftp, да еще и в корень сайта их кладу ибо лениво folder создать а потом еще путь каждый раз выписывать.

Насчет "снимает стиль окна" чуть заранее испугали. У меня там Treeview/ListView разделяются, и на Висте они в "крутом" стиле "explorer", не хотелось бы это дело показывать в стиле "аля-классик" даже временно, если мы конечно о том же.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654400
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бенедикт2) IMHO, разделитель должен себя вести в соответствии с общесистемными установками. Если уж пользователь поставил галку "Show window contents while dragging", пусть сам и смотрит на слайд-шоу.
Ну здесь я не соглашусь. Эта галка в свойства=> оформление=>эффекты находится, так?
Когда меняешь размер формы, то да, это автоматически применяется/не применяется.

А когда таскаешь разделитель, то это на вкус написателя программы. И сам майкрософт здесь никаких правил не соблюдает.
Классические примеры (два моих любимых):
1) Outlook Express - всегда мультфильм
2) Microsoft Fax (Консоль факсов) -всегда ездит палка/разделитель
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36654921
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77P.S. Мо быть мне кто объяснит все же: здесь все очень лихо прикладывают zip-ы, rar-ы а я туплю и не знаю как это сделать и вынужден класть файлы на, скажем так, не совсем свой ftp, да еще и в корень сайта их кладу ибо лениво folder создать а потом еще путь каждый раз выписывать.Просто здесь то, что приложено к сообщению, уже не прикладывается, если нажать кнопку "Предварительный просмотр". Т.е. написали сообщение, нажали "Предварительный просмотр", {отредактировали, опять нажали,} нажали "Browse...", добавили файл, нажали "Опубликовать". Я тоже не с первого раза понял.
Дмитрий77Насчет "снимает стиль окна" чуть заранее испугали. У меня там Treeview/ListView разделяются, и на Висте они в "крутом" стиле "explorer", не хотелось бы это дело показывать в стиле "аля-классик" даже временно, если мы конечно о том же.Нет, не о том же. Window Styles Дмитрий77Ну здесь я не соглашусь. Эта галка в свойства=> оформление=>эффекты находится, так?
Когда меняешь размер формы, то да, это автоматически применяется/не применяется.

А когда таскаешь разделитель, то это на вкус написателя программы.Да, эта галка. И считаю, что изменение размера формы, как и изменение размера панели является изменением размера окна. Я смотрю на Explorer, кстати, в качестве примера. Но согласен с тем, что это дело вкуса, по большому счёту.

Исходники в приложении. Замечания:
1) надо из формы функциональность выносить в класс;
2) сабклассинг реализован не совсем обоснованно сложно (overkill) для VB, но мне так было проще-быстрее, так как это готовые модули;
3) не уверен, что надо обрабатывать очистку фона, попробуйте в SubclsMe_EraseBackground возвращать и True, и False, если разницы нет, выкиньте;
4) сабклассинг выкинуть не получится, так как надо обрабатывать потерю захвата мыши (capture).
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36655454
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бенедикт,

спасибо. Так с ходу ничего не понял, но "Будем разбираться" на выходных или на след. неделе.
Ничего пока кроме спасибо не говорю и не спрашиваю, тем более дали комментарии. Знаю что Бенедикт плохого не предложит.

М.б. наглею конечно, не часто вы здесь появляетесь....а по графике вы здесь первый
Вот с этой задачей даже близко не справился:
Градиенты в Vista стиле, и в частности подложка под Toolbar
Т.е. хочется под тулбар подложить explorer-vista-style, мутно-зелено-синий градиент.
Решение для классич.стиля тулбара есть, но нужно именно под Windows-стилями включенными сделать. Собственно это если вдруг знаете.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36658122
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык, целый выходной угробил. Попробуем приложить чего получилось.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36658158
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эге, приложить получилось наконец, слава те...
Теперь не жалко потратить чуть времени на описание:
Бенедиктотличие в отрисовке между кодом, приведённым Antonariy-ем ( EasySplitter ) и примером ViewEx в том, что MFC-шная реализация (класс CSplitterWnd, см. WINSPLIT.CPP, если есть исходники MFC) 1) рисует на DC окна, а не экрана.
Ну вот, родил, рисуем на DC контейнера, естественно координаты пришлось пересчитывать.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Private Sub pDrawSplitter()
Dim lhDC As Long
Dim hOldBrush As Long
Dim crBackColor As Long
    'If IsWinVista Then
        lhDC = GetDC(m_oContainer.hWnd)
        crBackColor = SetBkColor(lhDC, vbWhite)
        hOldBrush = SelectObject(lhDC, m_hBrush)
        If (m_eOrientation = cSPLTOrientationVertical) Then
            PatBlt lhDC, m_oContainer.Left + m_lSplitPos,  0 , m_lSplitSize, m_oContainer.Height, PATINVERT
        Else
            PatBlt lhDC,  0 , m_oContainer.Top + m_lSplitPos, m_oContainer.Width, m_lSplitSize, PATINVERT
        End If
        SelectObject lhDC, hOldBrush
        SetBkColor lhDC, crBackColor
        ReleaseDC m_oContainer, lhDC
    'Else
    '    lhDC = CreateDCAsNull("DISPLAY", ByVal 0&, ByVal 0&, ByVal 0&)
    '    hOldBrush = SelectObject(lhDC, m_hBrush)
    '    PatBlt lhDC, m_tSplitR.Left, m_tSplitR.Top, m_tSplitR.Right - m_tSplitR.Left, m_tSplitR.Bottom - m_tSplitR.Top, PATINVERT
    '    SelectObject lhDC, hOldBrush
    '    DeleteDC lhDC
    'End If
End Sub
Бенедикт
3) не уверен, что надо обрабатывать очистку фона, попробуйте в SubclsMe_EraseBackground возвращать и True, и False, если разницы нет, выкиньте;
Смысл SetBkColor здесь не очень понимаю, но оставил, раз вставил...
Бенедикт2) на время таскания перемычки снимает стиль окна WS_CLIPCHILDREN, чтобы рисовать поверх всех дочерних окон.
Да, добавил, иначе оно под низ рисует, все сработало.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public Sub MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
...
         If Not (m_bFullDrag) Then
...
            '==================================
            'If IsWinVista Then
                wsStyle = GetWindowLong(m_oContainer.hWnd, GWL_STYLE)
                SetWindowLong m_oContainer.hWnd, GWL_STYLE, wsStyle And Not WS_CLIPCHILDREN '.picSplitMain
            'End If
            '=================================
            pDrawSplitter
...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Public Sub MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
...
         If Not m_bFullDrag Then
            pDrawSplitter
            '====================
            'If IsWinVista Then
                SetWindowLong m_oContainer.hWnd, GWL_STYLE, wsStyle
            'End If
            '====================
         End If
...

Исправил мелкий баг: при нажатии мышкой на разделителе после нажатия но до начала движения курсор разделителя не отображается
Код: plaintext
1.
2.
3.
4.
5.
Public Sub MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
...
         '====================================
         SetCursor m_hCursor 'без этого курсор исчезнет в момент нажатия
         '===================================
...
Бенедикт2) сабклассинг реализован не совсем обоснованно сложно (overkill) для VB, но мне так было проще-быстрее, так как это готовые модули;
4) сабклассинг выкинуть не получится, так как надо обрабатывать потерю захвата мыши (capture).
Здесь не понял об чем речь, фактически я его выкинул.
Ну, скажем так, конкретно в примере от Antonariy мне не нравится, что движение мыши стопорится границами формы.
У меня в конкретном приложении этого тьфу-тьфу автоматически не происходит, видимо потому что сабклассинг формы таки используется на предмет ограничения ее размеров, причем минимальные высота/ширина формы находятся в динамической зависимости от текущей ширины элементов, разделяемых сплиттером, пытаться вдумываться в это уже неохота.
Собственно все приложено целиком выше.
==================================
Но, в своем конкретном примере столкнулся с гораздо более сложным подвохом.
Все сделал как описано, а на TreeView иногда глючит.
Голову ломал долго.
Дело в том что я использую для Treeview стиль Or TVS_EX_FADEINOUTEXPANDOS
У меня разделяются Treeview и назовем так ТО_ЧТО_СПРАВА
Картинка (которая Splitter) берет на себя фокус когда делаешь на ней Mouse_down (tabstop=false естественно роли не играет)
При этом если фокус стоял на TreeView, то Treeview теряет фокус, механизьм фейдера срабатывает и если шустрый юзер резво двигает палку в сторону TreeView, то он будет наблюдать спецэффекты с разделителем в самом лучшем и непотребном виде, ибо в теч. 2сек работы фейдера перерисовка Treeview идет непрерывно и плевать ему на отмену стилей нашей картинки-разделителя.
Одним из способов решения конечно был отмена фейдера, но стиль этот мне пришелся по душе (к хорошему быстро привыкаешь).
Пытался отменять этот стиль временно по аналогии со стилем разделителя (т.е. по событию mouse_down до наступления mouse_up). Не помогло, ибо механизм запускается еще до mouse_down и отмены уже запущенного механизма не происходит.
Все же нашел способ извратиться:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
If IsWinVista Then
    OldSplitWindowProc = SetWindowLong(picSplitMain.hwnd, GWL_WNDPROC, _
        AddressOf NewSplitWindowProc)
End If
...
Public OldSplitWindowProc As Long

Public Function NewSplitWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    'для событий picSplitMain
    If (Msg = &H7) Then ' Const WM_SETFOCUS = &H7
        Debug.Print wParam
        If Form1.TreeView1.hwnd = wParam Then
            'Call SendMessage(wParam, &H7, 0&, 0&)
            Form1.TreeView1.SetFocus
        End If
    End If
    NewSplitWindowProc = CallWindowProc( _
        OldSplitWindowProc, hwnd, Msg, wParam, _
        lParam)
End Function
Иными словами, на Висте если разделитель принял фокус от TreeView, то фокус отфутболивается обратно и эффект фейдера не срабатывает, разделитель отрисовывается без глюков. (от SendMessage (WM_SETFOCUS ) я отказался, так как приводит к двойным фокусам, ну его...)
На самом деле при большом желании ситуацию воспроизвести все же возможно.
Например, (надо делать быстро) из TreeView переходим в другой контрол и не мешкая задвигаем разделитель в TreeView. Но это малореальные ситуации, и потом никак не приводит к вылету программы и прочим серьезным последствиям, поэтому думаю считать вопрос решенным и от фейдера не отказываться.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36659520
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

по splitter-у пока прочёл по диагонали, но есть замечания:
1) SetBkColor необходим, иначе XOR будет происходить с выбранным сейчас в контексте цветом фона, что есть величина случайная. Если сейчас выбран чёрный, разделителя просто не будет видно.
2) Сабклассинг нужен для отлова потери захвата (capture) мыши. Иногда он теряется (пример - пользователь нажал Ctrl+Esc), причём в программу не приходит при этом стандартных мышиных сообщений. Хорошо себя ведущий элемент управления обязан отлавливать потерю захвата. (Можно поллинг GetCapture() делать, но это некрасиво.)
3) Фокус - в MFC явно прописаны, дуплетом, SetCapture(); SetFocus(); при начале таскания. То есть фокус с текущего элемента управления уходит. Можно на это ориентироваться, можно нет, но такова вот стандартная реализация.
4) У меня мусор в виде ClipControls = False оставался, уберите, если ещё не убрали.

Остальное пока не смотрел.

По теме тулбара. Опять не вчитывался (увы-увы), но как-то показалось, что начали с градиентной заливки, кончили почему-то прозрачностью. 1) Висты у меня нет, поэтому вопрос - с помощью Theme Explorer или функции GradientFill() можно получить желаемую картинку? 2) "Прозрачность". Когда-то, кажется, была в VBPJ статья. На C пример описан здесь , куда-то пропавший из статьи код прикладываю, смысл: ReBar, в нём band(-ы) с битмапной подложкой, в band-е toolbar со стилем TBSTYLE_FLAT. Если я правильно понял, что требуется.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36660037
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктДмитрий77,
2) Сабклассинг нужен для отлова потери захвата (capture) мыши. Иногда он теряется (пример - пользователь нажал Ctrl+Esc), причём в программу не приходит при этом стандартных мышиных сообщений. Хорошо себя ведущий элемент управления обязан отлавливать потерю захвата. (Можно поллинг GetCapture() делать, но это некрасиво.)


пример - пользователь нажал Ctrl+Esc
да, действительно глючит причем если это сделать то дальнейшие мелкие глюки с перерисовками будут продолжаться.
С одной стороны ерунда: я бы никогда не додумался на это нажимать при таскании, пользователь еще может например рубильник компьютера из розетки вынуть и много чего еще.
Но с другой стороны: ну да. Но как вы сами отметили сабклассинг у вас заумный.
Если я правильно понял, то нужно что-то типа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    OldНечтоWindowProc = SetWindowLong(Нечто.hwnd, GWL_WNDPROC, _
        AddressOf NewНечтоWindowProc)
...
Public OldНечтоWindowProc As Long

Public Function NewНечтоWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    'для событий Нечто
    If (Msg = &H215) Then ' Const WM_CAPTURECHANGED = &H215
         To Do что-то
         Exit Sub '???
    EndIf
    NewНечтоWindowProc = CallWindowProc( _
        OldSplitWindowProc, hwnd, Msg, wParam, _
        lParam)
End Function
Именно так я понимаю сабклассинг, но здесь
1) Я так и не понял что есть НЕЧТО: форма, PictureSplitter...
2) Он скорее всего должен запускаться не по Form_Load и жить до конца работы проги.
А видимо стартовать по Mouse_down и принудительно выполнять Mouse_Up, т.е. возвращать стиль в норму и стирать сплиттер-картинку. Ну т.е. потеря захвата эквивалентна коду Mouse_up
В общем не дано мне с ходу понять чего делать, ваш вариант в силу накрученности понятно брать не хочу не буду (и не сумею, круто оч-чень).
А у меня там всего лишь Setup-форма, user ее один раз может подрегулирует...
Есть правда еще одно Aplication где я бы все это применил, но там уже все эти взаимные перемещения ListView/Treeview уже давно прописаны на VB по-детски, не рискнул бы с ходу взять все и перекраивать, все размеры, все координаты,вся идеология при таких заменах сразу едет...

Бенедикт3) Фокус - в MFC явно прописаны, дуплетом, SetCapture(); SetFocus(); при начале таскания. То есть фокус с текущего элемента управления уходит. Можно на это ориентироваться, можно нет, но такова вот стандартная реализация.
Просто "снимает стиль окна WS_CLIPCHILDREN, чтобы рисовать поверх всех дочерних окон" хорошо тогда, когда дочернее окно "не рыпается",любой рефреш дочернего окна смажет этот сплиттер кот. поверх а фейдер, это когда Treeview в стиле Explorer и при уходе фокуса треугольнички(кот. вместо плюсиков) медленно исчезают, соотв. TreeView автоперерисовывается. Но кстати если смотреть на висте в стандартный проводник, то фокус не уходит, хотя... там всегда непрерывная перерисовка и галка (обсуждали недавно) роли не играет.

БенедиктПо теме тулбара. 1) Висты у меня нет, поэтому вопрос - с помощью Theme Explorer или функции GradientFill() можно получить желаемую картинку?.
Так Win 7 в плане "красивостей" вроде то же самое.
Увы, увы...
с Theme Explorer удалось нашаманить только вот это
Код: plaintext
1.
        SetWindowTheme TreeView1.hwnd, StrPtr("explorer"),  0 
        SetWindowTheme ListView1.hwnd, StrPtr("explorer"),  0 
что впрочем уже не мало. В поиске этого нигде не нашел. StrPtr пнул туда буквально наугад со злости.

Если есть какие-то наметки, можно пошаманить, но нет уверенности что этот тулбар это именно "стиль". Дело в том, что он используется только в окнах Explorer. И еще в двух "родных" приложениях: Windows Mail и Fax and Scan. Причем в этих двух цвет темно синий а не мутно -зеленый. Конечно, если это "стиль", то правильнее научиться говорить "сим-сим откройся", чем писать новую книгу по HDC-магии и т.п. Но чтобы подбирать волшебное слово надо хотя бы точно знать что оно есть в словаре в принципе.

Реально рабочее красивое решение
http://www.vbforums.com/showthread.php?t=381167
при включенных стилях не работает (а именно ради стилей и стараемся, без стилей такого "не положено").

Бенедикткончили почему-то прозрачностью
Потому что если тулбар прозрачный, то под него хоть статическую картинку можно подложить (наверное). Я вертел долго этот ControlSpyV6, смотрел на эти планеты на черном фоне, но воспроизвести этот TB_TRANSPARENT у меня нормально не получилось даже через API-тулбар, а речь идет-таки о доработке VB-toolbar.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36660597
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77
> С одной стороны ерунда: я бы никогда не додумался на это нажимать при таскании, пользователь еще может например
> рубильник компьютера из розетки вынуть и много чего еще.

Я этим частенько пользуюсь, потому что по другому не получается "выйти" из режима таскания. :)
Вернее это самый быстрый способ выйти из режима таскания :)

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36660872
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Горбонос,
да нет, правы конечно
не обязательно ctrl+esc можно alt+tab, или напр. какое-нибудь окно всплыло внезапно, ну скажем реклама антивируса авира на бесплатной версии.
пока просто не понимаю как это по-простому сделать, чего и как сабклассить
(я выше сформулировал свои сомнения, кот. по делу вопроса)
>1) Я так и не понял что есть НЕЧТО: форма, PictureSplitter...
>2) Он скорее всего должен запускаться не по Form_Load и <не должен>жить до конца работы проги.
А видимо стартовать по Mouse_down и принудительно выполнять Mouse_Up, т.е. возвращать стиль в норму и стирать сплиттер-картинку. Ну т.е. потеря захвата эквивалентна коду Mouse_up

т.е. пример есть, но оч. крутой, если как-то по-простому разжуете, то думаю осилю
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36660965
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77
> т.е. пример есть, но оч. крутой, если как-то по-простому разжуете, то думаю осилю

К сожаленю, я глубоко не вникаю в код(не хватает времени )
И о каком из примеров идет речь?

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36661074
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Горбонос,

Критикуется Бенедиктом "моя" продукция (то что сделал из примера Antonariy с учетом примера Бенедикта)
EasySplitter_Code_Vista.zip
Сабклассинг я благополучно проигнорировал (речь о том что не надо игнорировать)

Пример нужного сабклассинга (думаю ключ в слове WM_CAPTURECHANGED) в примере Бенедикта,
но как отмечает сам автор сабклассинг там навороченно излишне сложен
Project2.rar

На время таскания перемычки с контейнера (который сплиттер)
"снимается стиль окна WS_CLIPCHILDREN, чтобы рисовать поверх всех дочерних окон"
основная беда, когда сплиттер потерял захват мыши (случайно) даже не в том, что остатки разделителя-картинки виднеются на экране какое-то время, пока не "подергали туда-сюда",
а в том, что WS_CLIPCHILDREN не возвращается назад, в норм. условиях он возвращается назад по событию mouse_up.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Public Sub MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
...
         If Not m_bFullDrag Then
            pDrawSplitter
            '====================
                 SetWindowLong m_oContainer.hWnd, GWL_STYLE, wsStyle
            '====================
         End If
...
В описанных условиях потери захвата код mouse_up не выполняется
Сабклассинг думаю должен востолнять это восстановление стиля по WM_CAPTURECHANGED
Т.е. задача придумать простой сабклассинг и вставить в первый пример.
...
Рейтинг: 0 / 0
Взаимное положение ListView/Treeview
    #36661336
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
держи :)

Я добавил модуль для сабклассинга.
сюда добавил перехват сообщений:
Код: plaintext
1.
2.
3.
4.
Private Sub picSplitMain_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
   Hook Me.picSplitMain.hwnd
   m_cSplitMain.MouseDown Button, Shift, x, y
End Sub
и в новой виндовой процедуре в новом модуле обработку смены фокуса.

Посмотри и допиляй как тебе нужно :)
...
Рейтинг: 0 / 0
25 сообщений из 59, страница 1 из 3
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Взаимное положение ListView/Treeview
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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