powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
14 сообщений из 14, страница 1 из 1
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36491413
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С рисунком проще объяснить.
То что справа-это PictureBox (или Frame,не суть) напичканный элементами
Создается так:
Код: plaintext
1.
2.
3.
4.
5.
6.
   Set gForm1 = New frmControls
    Set gPictureSetup = frmControls.PictureSetup
...

        SetParent gPictureSetup.hWnd, hWndParent 'т.е. папой назначается dialog
        gPictureSetup.Visible = True
...

Settings -это бывшая кнопка Help, переименованная, hook-нутая и move-нутая.
В Settings Tab-ом можно прийти без проблем, например.
А вот то что внутри Picturebox, туда клавиатурой не дойти.
Как сделать так чтоб TabStop были как бы общие для Original и Post-Implemented контролов.
Я естественно уже пытался впихивать элементы по одному вместо "Рамки-картинки" (это кстати замучаешься, но не суть). С фокусом у них все нормализуется, но при этом они могут вести себя неадеквато, скажем Option1/Option2 вообще работать не будут, а чего-нибудь другое может не срабатывать или не дай бог наделять себя ф-циями какого-нибудь Open/Cancel. Посему мой вариант Оптимальный, т.к. он не глючит с функционалом да и легко модифицируется.
Но все таки: как сделать Фокус по TAB для выделенных элементов?

...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36491682
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жесть. Я не слышал, чтобы кто-то пытался это сделать, вряд ли добьетесь успеха, двигаясь в этом направлении. К счастью, кое-что о табуляции я уже слышал, и в посках источника нашел направление , которое мне кажется более перспективным.

Jah loves you.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36492010
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,
> направление, которое мне кажется более перспективным
этот пример я пытался разбирать, но он показался мне сложноватым.
Там "набор доп.элементов" берется из формы-ресурса и все отслеживается через сообщения (хотя и согласен, нет описанной проблемы).


Я отталкивался от другого примера, кажется этот
http://www.planet-source-code.com/Upload_PSC/ftp/CommonDial196237142006.zip

Поступаю проще. Создаю исх.форму в VB и работаю с ее копией, помещая элементы копии на диалог. Это дает мне возможность использовать стандартный VB функционал, прописанный в исходной VB-форме. При этом если доп.набор поставляется внутри рамки-картинки, то все элементы внутри рамки функционируют безглючно как мне надо, но не получают фокуса по TAB, если их добавлять по одиночке, то возможны глюки, если эти элементы (vb provided) начинать пытаться отслеживать через WinProc, то с оч. хорошей вероятностью получаем сбой из-за CopyMemory при попытке расшифровать месседжи с соотв.вылетом программы.

Таким образом, у меня видятся 3 варианта.
1) самый простой: забить на эти TAB, итак неплохо
2) самый красивый: таки найти ответ на свой вопрос
3) забить на то что сделано и осознано и заняться разборкой вышеуказанного примера потратив на это еще кучу времени с возможным появлением еще кучи вопросов и проблем.

Заметьте, что мой вариант очень гибкий: я могу вставлять в рамку-картинку-форму все что угодно и это быстро будет работать, посему грех на этот метод плевать и начинать все сначала.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36492048
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 и 3 будут сравнимы по затратам времени, но 2 не гарантирует, что результат вообще будет достигнут.

Если все-таки будете терзать 2, то имейте ввиду, что картинка получает фокус, а вам с помощью IOLEInPlaceActiveObject нужно попытаться удержать его внутри при нажатии TAB. Лучше при этом заменить картинку на Usercontrol-контейнер.

Jah loves you.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36492255
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,
>Usercontrol-контейнер
это кто такой? OLE который? Если это он, то я его позавчера мучил и он мне не понравился, очень наглый какой-то и с подозрениями на глючность.
Я сначала делал Frame, но Frame глючит с отображением Option1/2 и т.п. при применении XP/Vista style, поэтому поменял его на потребный Picture.

>IOLEInPlaceActiveObject
>не гарантирует, что результат вообще будет достигнут

Думаете не стоит?
>
http://www.vbaccelerator.com/home/VB/code/Techniques/Trapping_The_Tab_Key_in_a_UserControl_with_IOLEInPlaceActiveObject/article.asp

>The code provided here is based on code and a Type Library put together
там что еще какие-то доп.Type Library надо добавлять? Не чистые API? Если так, то оно заранее не оч. нравится.

>3) забить на то что сделано и осознано и заняться разборкой вышеуказанного примера потратив на это еще кучу времени с возможным появлением еще кучи вопросов и проблем.

М.б. и стоит попробовать...
Тогда сразу несколько вопросов:

1) Форма-ресурс естественно рисуется в C++ ?
Думаю да. Даже знаю из какого App выдернуть готовую как мне нужно.
2) В примере ресурс добавлен "в Dll". В свой exe его запихнуть можно?
3)
Dim tNMH As NMHDR
CopyMemory tNMH, ByVal lParam, Len(tNMH)
глючить не будет? если элементы будут добавлены из формы-ресурса а не формы VB?
Потому как у меня в коде забабахано

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Public Function OFNHookProc(ByVal hWnd As Long, _
                            ByVal uMsg As Long, _
                            ByVal wParam As Long, _
                            ByVal lParam As Long) As Long
...
                Case CDN_INITDONE
...
                    OldWindowProc = SetWindowLong( _
                        hwndParent, GWL_WNDPROC, _
                        AddressOf NewWindowProc)
а потом
Код: plaintext
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.
Private Function NewWindowProc(ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
   Dim tNMH As NMHDR
    ' If we're being destroyed,
    ' restore the original WindowProc.
    If msg = WM_NCDESTROY Then
        Debug.Print "WM_NCDESTROY"
        SetWindowLong _
            hWnd, GWL_WNDPROC, _
            OldWindowProc
    End If
'    If msg = WM_COMMAND Then
'        Debug.Print "WM_COMMAND-" & wParam
'        'Debug.Print gBT.hWnd
'        CopyMemory tNMH, ByVal lParam, Len(tNMH)
'        'Debug.Print "tNMH.code-" & tNMH.hwndFrom
'        Select Case tNMH.code
'        'End Select
'    End If

    ' See if this is a WM_SIZE or WM_SIZING or WM_SHOWWINDOW message.
    If msg = WM_SIZE Or WM_SIZING Or WM_SHOWWINDOW Then
        ChangeOurFramePosition hWnd
    End If
    'Debug.Print msg
    ' Continue normal processing. VERY IMPORTANT!
    NewWindowProc = CallWindowProc( _
        OldWindowProc, hWnd, msg, wParam, _
        lParam)
End Function

Дело в том, что OFNHookProc не позволяет получить WM_SIZE or WM_SIZING , поэтому приходится закладывать NewWindowProc

И, смотрите в NewWindowProc, если gBT это кнопка VB-provided, то
CopyMemory tNMH, ByVal lParam, Len(tNMH) вызывает сбой, т.е. использовать расшифровку WM_COMMAND не представляется возможным.

Я боюсь столкнуться с этой проблемой и стать в тупик.
Хотя в примере "с ZIP" глюков нету, но там не используется OFN_RESIZE.( Если resize не делать то NewWindowProc не нужен. )
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36493074
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77это кто такой?Ууу, как все запущено. Нет, это не OLE. Правой кнопкой по окну Project explorer — Add — UserControl. Свойство ControlContainer выставить в True. C точки зрения стилей все будет как с Picture.

Дмитрий77Думаете не стоит?Я думаю так: вы взялись перекраивать стандартные системные диалоги самым грубым и прямолинейным способом, на уровне окон, не обладая на подходящем уровне знаниями как работают ни диалоги ни окна вообще, при этом задавая высокую планку качества и продвигаясь вслепую. Каковы, по-вашему, ваши шансы взять эту планку в разумный промежуток времени? По-моему невелики. Я бы в такой ситуации сделал свой диалог с блекджеком и шлюхами за пару часов из обычной формы, а остальное время потратил на тот функционал, ради которого затевалась прога.

Дмитрий77там что еще какие-то доп.Type Library надо добавлять? Не чистые API? Если так, то оно заранее не оч. нравится.Это не арт-объект, а инструмент, либо вы его используете, либо нет, категория "нравится/не нравится" здесь не применима.
Библиотеки типов не кусаются и нужны только на этапе компиляции, таскать их с готовой программой не надо, если проблема в этом.

Дмитрий771) Форма-ресурс естественно рисуется в C++ ?Нет. Она либо рисуется в Visual Studio .NET (откройте там res-файл), либо компилируется из rc+h-файлов в тот же res. Можно и без h, но IDC-константы нужно заменить значениями.

Дмитрий772) В примере ресурс добавлен "в Dll". В свой exe его запихнуть можно?Думаю да, попробуйте. Насколько я понял, в функцию GCommonDialog.VBGetOpenFileName нужно будет передать App.hInstance вместо того, что возвращает LoadLibrary.

Дмитрий77И, смотрите в NewWindowProc, если gBT это кнопка VB-provided, то
CopyMemory tNMH, ByVal lParam, Len(tNMH) вызывает сбой, т.е. использовать расшифровку WM_COMMAND не представляется возможным.Еще бы, диалог не в курсе, что вы там за окна на него налепили.

Дмитрий773)
Dim tNMH As NMHDR
CopyMemory tNMH, ByVal lParam, Len(tNMH)
глючить не будет?Думаю нет, потому что в этом случае диалог сам все рисует и обо всех окнах знает.

Jah loves you.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36493413
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, хорошо, попытаемся пойти другим путем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Public Function OFNHookProc(ByVal hWnd As Long, _
                            ByVal uMsg As Long, _
                            ByVal wParam As Long, _
                            ByVal lParam As Long) As Long
...
      Case WM_NOTIFY
...
                Case CDN_INITDONE
                    '======================================
                    hWndParent = GetParent(hWnd)
                    SetOurFramePosition hWndParent
                    OldWindowProc = SetWindowLong( _
                        hWndParent, GWL_WNDPROC, _
                        AddressOf NewWindowProc)
...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Private Sub SetOurFramePosition(ByVal hWndParent As Long)
...
    'элементы справа через API (с frmControls только считываем местоположение, все через API)
    'Options:
    retval = CreateWindowEx( 0 , "Button", "All", WS_CHILD Or BS_AUTORADIOBUTTON, _
        pt.x + frmControls.OptionAll.Left, frmControls.OptionAll.Top, _
        frmControls.OptionAll.Width, frmControls.OptionAll.Height, hWndParent,  0 , App.hInstance, ByVal  0 &)
    ShowWindow retval,  1 
    retval = CreateWindowEx( 0 , "Button", "Current", WS_CHILD Or BS_AUTORADIOBUTTON, _
        pt.x + frmControls.OptionCurrent.Left, frmControls.OptionCurrent.Top, _
        frmControls.OptionCurrent.Width, frmControls.OptionCurrent.Height, hWndParent,  0 , App.hInstance, ByVal  0 &)
    ShowWindow retval,  1 
    retval = CreateWindowEx( 0 , "Button", "Selected", WS_CHILD Or BS_AUTORADIOBUTTON, _
        pt.x + frmControls.OptionSelected.Left, frmControls.OptionSelected.Top, _
        frmControls.OptionSelected.Width, frmControls.OptionSelected.Height, hWndParent,  0 , App.hInstance, ByVal  0 &)
    ShowWindow retval,  1 
Нарисовали 3 Options, они переключаются, вроде все корректно.
Через NewWindowProc хотим отслеживать события от них:
Код: plaintext
1.
2.
3.
4.
5.
Private Function NewWindowProc(ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
...
    If msg = WM_COMMAND Then
        lNotify = Get_HiWord(wParam)
        lCtrlID = Get_LoWord(wParam)
        Debug.Print "WM_COMMAND-" & lNotify & "/" & lCtrlID & "/" & wParam

CopyMemory там вообще ни к месту, надо делать Get_HiWord Get_LoWord
Но при нажатии именно на них WM_COMMAND появляется, но ...дебаг дает нуль информации
WM_COMMAND-0/0/0
WM_COMMAND-0/0/0
WM_COMMAND-0/0/0
Где опять напортачил?
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36493777
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyДмитрий77это кто такой?Ууу, как все запущено. Нет, это не OLE. Правой кнопкой по окну Project explorer — Add — UserControl. Свойство ControlContainer выставить в True. C точки зрения стилей все будет как с Picture.
Кажется я один раз такой сваял лет 5 тому назад. Задолбался потом на другом PC прогу запускать, пришлось заново компилировать.

AntonariyДмитрий77там что еще какие-то доп.Type Library надо добавлять? Не чистые API? Если так, то оно заранее не оч. нравится.Это не арт-объект, а инструмент, либо вы его используете, либо нет, категория "нравится/не нравится" здесь не применима.
Библиотеки типов не кусаются и нужны только на этапе компиляции, таскать их с готовой программой не надо, если проблема в этом.
Понятно, либо не используем.

AntonariyДмитрий771) Форма-ресурс естественно рисуется в C++ ?Нет. Она либо рисуется в Visual Studio .NET (откройте там res-файл), либо компилируется из rc+h-файлов в тот же res. Можно и без h, но IDC-константы нужно заменить значениями.
Это я все понял, я имел ввиду Microsoft Visual Studio VC++ 6.0 У меня VC2005 Express Edition, там кажется этого нет. А в VC 6.0 конечно подредактировать получилось, rc-res это я разобрался. Но dll как не возился не родил, м.б. я чего-то попортил в своем старом VC6++, тотому что нек. компоненты из VC98 мне мешали нормально компилировать в VC2005, я какие-то файлы паковал и т.п. То он на отсутствие h.ругается, короче на это пока забил.

AntonariyДмитрий772) В примере ресурс добавлен "в Dll". В свой exe его запихнуть можно?Думаю да, попробуйте. Насколько я понял, в функцию GCommonDialog.VBGetOpenFileName нужно будет передать App.hInstance вместо того, что возвращает LoadLibrary.
Понимаете, автор того примера вроде как это и задумал, т.е. в среде VB берем ресурс из dll, а если exe, то вроде как из своего res, вы посмотрите код. А на деле только из dll. Уберите dll из папки с exe, и ни фига не запустится. Скажем прямо, мне напр. эту "dll" за собой тащить неохота.

AntonariyДмитрий773)
Dim tNMH As NMHDR
CopyMemory tNMH, ByVal lParam, Len(tNMH)
глючить не будет?Думаю нет, потому что в этом случае диалог сам все рисует и обо всех окнах знает.
Ну этот вопрос я решил (в предыдущем топике);кстати на CopyMemory он все равно выплевывался в этом месте. Но все равно кроме нулей ничего не получилось.

Вообще говоря тот пример хитрый, с ним надо разбираться отдельно. М.б. потом, но с ходу мне там многое не понравилось.

Ну а теперь о главном.
AntonariyДмитрий77Думаете не стоит?Я думаю так: вы взялись перекраивать стандартные системные диалоги самым грубым и прямолинейным способом, на уровне окон, не обладая на подходящем уровне знаниями как работают ни диалоги ни окна вообще, при этом задавая высокую планку качества и продвигаясь вслепую. Каковы, по-вашему, ваши шансы взять эту планку в разумный промежуток времени? По-моему невелики. Я бы в такой ситуации сделал свой диалог с блекджеком и шлюхами за пару часов из обычной формы, а остальное время потратил на тот функционал, ради которого затевалась прога.
"Свой диалог с блекджеком и шлюхами за пару часов из обычной формы" меня точно не устраивает. Согласен, планка высоковата, но нормальное приложение должно выглядеть нормально, начальства надо мной не стоит, я пишу в свое удовольствие. "самым грубым и прямолинейным способом"-ну почему же, я отталкивался от конкретного примера, я его приводил кажется выше.

Короче взял я эту планку. Взбесили меня эти табы. Ухватился за собственную идею: если добавляешь элементы "по одному", а не в картинке-контейнере, то все работает корректно.

Почитав про всю эту жуть, взглянув на ваш tlb и безнадежно просидев над супер-деталями супер-примера, я таки решил идти пл-элементно, ибо это проще в 100раз всего этого ужаса и добить свой вариант. При этом передо мной встало еще несколько конкретных нехилых вопросов, но по сравнению с "жутью" это тоже оказалось решаемо.

1) Как вернуть ГРУППУ радио-кнопкам, если я добавляю их без рамки. Решение:
Код: plaintext
1.
2.
    SendMessage gOptionAll.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
    SendMessage gOptionCurrent.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
    SendMessage gOptionSelected.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
2) Как сделать так, чтобы на нач.этапе фокус не скакал по всем трем. Решение:
Код: plaintext
    SendMessage gOptionAll.hWnd, BM_CLICK,  0 ,  0 
3) Как перекинуть Label на диалог (у него нет hwnd). Через API искал но без большого энтузиазма, т.к. на примере созданных через API RadioButton предполагал проблемы со шрифтами.
Решение: а текст как раз можно вставить в рамку.
4) Как сделать так чтобы эти тексты-фреймы не получали фокус (а сами фреймы заразы его как раз получают)
Решение: для фреймов сделать enabled=false.
5) К сожалению Textbox со свойством Locked=false выглядит серым и не получает фокуса.
Решение:Locked=true Подправим его поведение потом в коде...
6) Добавленным элементам плевать на TabIndex,а надо чтоб TAB скакал сверху вниз.
Решение:
Код: plaintext
1.
2.
3.
4.
    SetParent gCheckSplit.hWnd, hWndParent
    gCheckSplit.Visible = True
...
    SetParent gTextTo.hWnd, hWndParent
    gTextTo.Visible = True
Элемент для кот. SetParent сделали позже будет иметь меньший TabIndex на диалоге, т.е. сначала
gTextTo, а потом gCheckSplit, т.е. parentы надо устанавливать сверху вниз.

Что я получил -таки: отсутствие необходимости разбираться с каждым WM_COMMAND и выяснять, что там диалог знает или не знает и почему WM_COMMAND бракованная.

Т.е. я работаю с формой VB обычным образом и мне доступна детская "понятная" среда, не требующая супер-знаний и доп. копаний в сложных вещах.

Ниже привожу фрагменты кода и 2 картинки. Естественно ободки фреймов я оставил лишь для иллюстрации и их не будет.

Внедряемые объекты:
'внедряемые доп. элементы диалога
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public gForm1 As Form
Public gFrameLabelPages As Frame 'содержит надпись Pages:
Public gTextPages As TextBox
Public gOptionAll As OptionButton
Public gOptionCurrent As OptionButton
Public gOptionSelected As OptionButton
Public gFrameLabelFromTo As Frame 'содержит надписи From и To
Public gTextFrom As TextBox
Public gVScrollFrom As VScrollBar
Public gTextTo As TextBox
Public gVScrollTo As VScrollBar
Public gCheckSplit As CheckBox

Запуск и уничтожение диалога:

Код: plaintext
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.
      .flags = OFN_EXPLORER Or OFN_ENABLEHOOK Or OFN_ENABLESIZING Or OFN_HIDEREADONLY
      .fnHook = FARPROC(AddressOf OFNHookProc)
..
'========================================
    'Prepare the controls for CommonDialog
    Set gForm1 = New frmControls
    Set gFrameLabelPages = frmControls.FrameLabePages
    Set gOptionAll = frmControls.OptionAll
    Set gOptionCurrent = frmControls.OptionCurrent
    Set gOptionSelected = frmControls.OptionSelected
    Set gLabelFrom = frmControls.LabelFrom
    Set gLabelTo = frmControls.LabelTo
    Set gTextFrom = frmControls.TextFrom
    Set gVScrollFrom = frmControls.VScrollFrom
    Set gTextTo = frmControls.TextTo
    Set gVScrollTo = frmControls.VScrollTo
    Set gCheckSplit = frmControls.CheckSplit
    Set gFrameLabelFromTo = frmControls.FrameLabelFromTo
'========================================
    Call GetOpenFileName(OFN)
'========================================
    Rem Release resources
    Set gFrameLabelPages = Nothing
    Set gOptionAll = Nothing
    Set gOptionCurrent = Nothing
    Set gOptionSelected = Nothing
    Set gLabelFrom = Nothing
    Set gLabelTo = Nothing
    Set gTextFrom = Nothing
    Set gVScrollFrom = Nothing
    Set gTextTo = Nothing
    Set gVScrollTo = Nothing
    Set gCheckSplit = Nothing
    Set gFrameLabelFromTo = Nothing
    Unload frmControls
    Set gForm1 = Nothing
'========================================
End Sub

'hook
Код: plaintext
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.
Public Function OFNHookProc(ByVal hWnd As Long, _
                            ByVal uMsg As Long, _
                            ByVal wParam As Long, _
                            ByVal lParam As Long) As Long

 ...
     Select Case uMsg
      Case WM_INITDIALOG
        hWndParent = GetParent(hWnd)
        Call SendMessage(hWndParent, CDM_SETCONTROLTEXT, ID_HELP, ByVal "Settings")
        hItem = GetDlgItem(hWndParent, ID_HELP)
        If IsWindowEnabled(hItem) Then Call EnableWindow(hItem,  0 )
      Case WM_NOTIFY
            CopyMemory tNMH, ByVal lParam, Len(tNMH)
            Select Case tNMH.code
                Case CDN_HELP 'Help clicked (that is settings)
                    FormJPEG.Show  1 
                    '-------здесь сидим и ждем пока пользователь закроет FormJPEG----
                    SendMessage GetParent(hWnd), WM_SETFOCUS,  0 &,  0 &
                Case CDN_TYPECHANGE
                    hWndParent = GetParent(hWnd)
                    hItem = GetDlgItem(hWndParent, ID_FILETYPE)
                    Index = SendMessage(hItem, CB_GETCURSEL, ByVal  0 &, ByVal  0 &) +  1 
                    hItem = GetDlgItem(hWndParent, ID_HELP)
                    'SetWindowLong hItem, GWL_STYLE, GetWindowLong(hItem, GWL_STYLE) Or WS_DISABLED
                    If Index =  4  Then 'пользователь решил сохранять как JPEG
                        If Not (IsWindowEnabled(hItem)) Then Call EnableWindow(hItem,  1 )
                    Else
                        If IsWindowEnabled(hItem) Then Call EnableWindow(hItem,  0 )
                    End If
                Case CDN_INITDONE
                    '======================================
                    hWndParent = GetParent(hWnd)
                    SetOurFramePosition hWndParent
                    'Call WinProc
                    OldWindowProc = SetWindowLong( _
                        hWndParent, GWL_WNDPROC, _
                        AddressOf NewWindowProc)
                    '======================================
                Case Else
            End Select
      Case Else
   End Select
End Function
Установка доп.набора элементов(основная) SetOurFramePosition hWndParent
Код: plaintext
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.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
Private Sub SetOurFramePosition(ByVal hWndParent As Long)
    Dim rc As RECT, rcDesk As RECT  'rc-это диалог
    Dim rL As RECT, hLV As Long, pt As POINTAPI 'LIST1
    Dim rCN As RECT, hCN As Long, ptCN As POINTAPI 'CANCEL button
    Dim rHL As RECT, hHL As Long, ptHL As POINTAPI 'HELP button
    Dim rSB As RECT 'StatusBar
    Dim adwParts( 2 ) As Long 'Statusbar Parts:0,1,2-3шт
    Dim lRet As Long 'хранение StatusBar шрифт
    
    'установка элементов
    GetWindowRect hWndParent, rc    ' Common Dialog
    'Find the ListView (LIST1) position to calculate where insert наши элементы
    hLV = GetDlgItem(hWndParent, ID_LIST1)  ' LIST1 handle
    GetWindowRect hLV, rL             ' LIST1 rectangle
    Rem In <pt> I will set the Right & Top of ListView LIST1
    pt.x = rL.Right
    pt.y = rL.Top
    ScreenToClient hWndParent, pt
    
    'установка элементов правой "панели"
    'gFrameLabelPages.Height = (rL.Bottom - rL.Top) + pt.y
    gFrameLabelPages.Left = pt.x
    gFrameLabelPages.Top = frmControls.LabePages.Top
    gOptionAll.Left = pt.x + frmControls.OptionAll.Left
    gOptionAll.Top = frmControls.OptionAll.Top
    gOptionCurrent.Left = pt.x + frmControls.OptionCurrent.Left
    gOptionCurrent.Top = frmControls.OptionCurrent.Top
    gOptionSelected.Left = pt.x + frmControls.OptionSelected.Left
    gOptionSelected.Top = frmControls.OptionSelected.Top
    gFrameLabelFromTo.Left = pt.x
    gFrameLabelFromTo.Top = frmControls.LabelFrom.Top
    gTextFrom.Left = pt.x + frmControls.TextFrom.Left
    gTextFrom.Top = frmControls.TextFrom.Top
    gVScrollFrom.Left = pt.x + frmControls.VScrollFrom.Left
    gVScrollFrom.Top = frmControls.VScrollFrom.Top
    gTextTo.Left = pt.x + frmControls.TextTo.Left
    gTextTo.Top = frmControls.TextTo.Top
    gVScrollTo.Left = pt.x + frmControls.VScrollTo.Left
    gVScrollTo.Top = frmControls.VScrollTo.Top
    gCheckSplit.Left = pt.x + frmControls.CheckSplit.Left
    gCheckSplit.Top = frmControls.CheckSplit.Top
    
    rc.Right = rL.Right + gFrameLabelPages.Width 'ширина диалога увеличивается на заданный размер
    
    'Find the Cancel Button (CANCEL) position to calculate where insert the HELP button
    hCN = GetDlgItem(hWndParent, ID_CANCEL) ' CANCEL handle
    GetWindowRect hCN, rCN             ' CANCEL rectangle
    Rem In <ptCN> I will set the Right & Top of button CANCEL
    ptCN.x = rCN.Right
    ptCN.y = rCN.Top
    ScreenToClient hWndParent, ptCN
    
    'Find the Help Button (HELP) position to calculate
    hHL = GetDlgItem(hWndParent, ID_HELP)  ' HELP handle
    GetWindowRect hHL, rHL             ' HELP rectangle
    Rem In <ptCN> I will set the Right & Top of button HELP
    ptHL.x = rHL.Right
    ptHL.y = rHL.Top
    ScreenToClient hWndParent, ptHL
    'сдвигаем HELP вправо от CANCEL, размещаем посередине нашей панели, и увеличиваем ее ширину в 1,5раза
    MoveWindow hHL, ptCN.x + (rc.Right - rCN.Right) /  2  - (rHL.Right - rHL.Left) *  3  /  4 , ptCN.y, _
    (rHL.Right - rHL.Left) *  1 . 5 , rHL.Bottom - rHL.Top,  1 
    'только теперь делаем HELP видимым, не использовали OFN_SHOWHELP,лишнее пустое место внизу не нужно
    SetWindowLong hHL, GWL_STYLE, GetWindowLong(hHL, GWL_STYLE) Or WS_VISIBLE '

    'Statusbar create так и быть через API
    hStatusBarWnd = CreateStatusWindowA(WS_CHILD Or WS_VISIBLE, "StatusBar Text", hWndParent,  0 )
    GetWindowRect hStatusBarWnd, rSB ' StatusBar rectangle
    'высоту формы увеличиваем на высоту StatusBar
    rc.Bottom = rc.Bottom + (rSB.Bottom - rSB.Top)
    'устанавливаем шрифт в StatusBar как в родительской форме
    'Set the font of the status bar using the WM_SETFONT by getting the font from
    'this form using the WM_GETFONT
    lRet = SendMessage(hWndParent, WM_GETFONT,  0 ,  0 )
    SendMessage hStatusBarWnd, WM_SETFONT, lRet,  0 
    'установка размеров панелей в Statusbar
    adwParts( 0 ) =  200 
    adwParts( 1 ) =  350 
    adwParts( 2 ) = - 1  'до конца формы
    SendMessage hStatusBarWnd, SB_SETPARTS, ByVal  3 , adwParts( 0 )
    'Установка текста панелей(что-нибудь напишем для теста пока)
    SetText hStatusBarWnd,  0 , SBT_SUNKEN, "Size: 1 156 697 bytes"
    SetText hStatusBarWnd,  1 , SBT_SUNKEN, "Pages: 1/52"
    SetText hStatusBarWnd,  2 , SBT_SUNKEN, "Resolution: 204*98 dpi"

    'Use Elements in this Common Dialog
    'добавляем снизу вверх, это влияет на последовательность TabIndex c т.зр.диалога
    'мы хотим чтоб TAB продвигался сверху вниз Options->TextFrom->TextTo->CheckSplit
    SetParent gCheckSplit.hWnd, hWndParent
    gCheckSplit.Visible = True
    SetParent gVScrollTo.hWnd, hWndParent
    gVScrollTo.Visible = True
    SetParent gTextTo.hWnd, hWndParent
    gTextTo.Visible = True
    SetParent gVScrollFrom.hWnd, hWndParent
    gVScrollFrom.Visible = True
    SetParent gTextFrom.hWnd, hWndParent
    gTextFrom.Visible = True
    SetParent gFrameLabelFromTo.hWnd, hWndParent 'вместо LabelTo и LabelTrom,label не имеет hwnd
    gFrameLabelFromTo.Visible = True 'enabled=false,чтобы не останавливаться по TAB
    SetParent gOptionSelected.hWnd, hWndParent
    gOptionSelected.Visible = True
    SetParent gOptionCurrent.hWnd, hWndParent
    gOptionCurrent.Visible = True
    SetParent gOptionAll.hWnd, hWndParent
    gOptionAll.Visible = True
    SetParent gFrameLabelPages.hWnd, hWndParent 'вместо LabelPages,label не имеет hwnd
    gFrameLabelPages.Visible = True 'enabled=false,чтобы не останавливаться по TAB

    Rem ----------------------------------------------------
    Rem Screen center т.е. выводим это дело на экран
    Rem ----------------------------------------------------
    rcDesk.Left =  0 
    rcDesk.Top =  0 
    rcDesk.Right = Screen.Width / Screen.TwipsPerPixelX
    rcDesk.Bottom = Screen.Height / Screen.TwipsPerPixelY
    SetWindowPos hWndParent,  0 , _
            (rcDesk.Right - (rc.Right - rc.Left)) /  2 , _
            (rcDesk.Bottom - (rc.Bottom - rc.Top)) /  2 , _
            rc.Right - rc.Left, _
            rc.Bottom - rc.Top,  0 
    
    'теперь исправляем все то что "сглючило"
    'StatusBar перемещаем только после прорисовки формы на подготовленное заранее пространство внизу
    'By default, our new status bar assumes its own position and
    'size. Use the MoveWindow API to move it to the bottom of the form
    SendMessage hStatusBarWnd, WM_SIZE,  0 ,  0 
    'восстановление работы Option1/2/3 в группе, почему-то они забыли что были группой
    SendMessage gOptionAll.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
    SendMessage gOptionCurrent.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
    SendMessage gOptionSelected.hWnd, BM_SETSTYLE, BS_AUTORADIOBUTTON,  0 
    'повторная инициализация OptionButtonGroup, чтобы фокус по TAB с самого начала получала только
    'одна из них, а не все подряд, это тоже надо восстановить
    SendMessage gOptionAll.hWnd, BM_CLICK,  0 ,  0 
End Sub

доп. Winproc для отслеживания WM_SIZE ибо из hook это не отслеживается
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Private Function NewWindowProc(ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As WINDOWPOS) As Long
    ' If we're being destroyed,
    ' restore the original WindowProc.
    If msg = WM_NCDESTROY Then
        SetWindowLong _
            hWnd, GWL_WNDPROC, _
            OldWindowProc
    End If
    ' See if this is a WM_SIZE or WM_SIZING or WM_SHOWWINDOW message.
    If msg = WM_SIZE Or WM_SIZING Or WM_SHOWWINDOW Then
        ChangeOurFramePosition hWnd
    End If
    ' Continue normal processing. VERY IMPORTANT!
    NewWindowProc = CallWindowProc( _
        OldWindowProc, hWnd, msg, wParam, _
        lParam)
End Function
Корректировка положения StatusBar и перерисовка нек. элементов диалога, кот. не перерисовываются автоматически при изменении его размеров.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Private Sub ChangeOurFramePosition(ByVal hWndParent As Long)
    Dim rc As RECT, rcDesk As RECT
    Dim rL As RECT, hLV As Long, pt As POINTAPI ' LIST
    'некоторые элементы требуют перерисовки при Диалог_Resize
    'установка элементов
    GetWindowRect hWndParent, rc    ' Common Dialog
    'Find the ListView (LIST) position to calculate where insert наши элементы
    'почему-то здесь надо использовать ID_LIST вместо ID_LIST1
    hLV = GetDlgItem(hWndParent, ID_LIST) 'ID_LIST (LIST handle)
    GetWindowRect hLV, rL ' LIST rectangle
    'In <pt> I will set the Right & Top of ListView LIST
    pt.x = rL.Right
    pt.y = rL.Top
    ScreenToClient hWndParent, pt
    
    gFrameLabelPages.Top = frmControls.LabePages.Top * Screen.TwipsPerPixelY
    gFrameLabelPages.Left = pt.x * Screen.TwipsPerPixelX
    gFrameLabelFromTo.Top = frmControls.LabelFrom.Top * Screen.TwipsPerPixelY
    gFrameLabelFromTo.Left = pt.x * Screen.TwipsPerPixelX
    
    'чтоб Statusbar не отставал от формы
    SendMessage hStatusBarWnd, WM_SIZE,  0 ,  0 
End Sub

И собственно чего (результат) и из чего (vb.form) получилось.





Antonariyне обладая на подходящем уровне знаниями, при этом задавая высокую планку качества и продвигаясь вслепую. Каковы, по-вашему, ваши шансы взять эту планку в разумный промежуток времени? По-моему невелики.
Знаний "в разумный промежуток времени" и правду не наберешь, согласен.
Но те что есть все же иногда позволяют "взять планку" в указанный промежуток.
Знаний кстати слегка прибавилось, хотя и не "в том объеме", кот. предполагался. А те примеры мне и вправду пока не по зубам.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36494146
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что ж, примите искренние поздравления :) Терпенье и труд все перетрут.

Дмитрий77Кажется я один раз такой сваял лет 5 тому назад. Задолбался потом на другом PC прогу запускать, пришлось заново компилировать.Походе вы тогда написали отдельный *.ocx и не пользовались инсталляторами. Получился разброд в версиях.

Дмитрий77У меня VC2005 Express Edition, там кажется этого нет.
Если вы трепетно относитесь к легальности ПО, можете вроде бы ничего не нарушая установить клиентские компоненты от SQL Server 2005 версии Standart или выше, кусок от Visual Studio 2005, идущий в комплекте, умеет работать с файлами ресурсов наверняка.

Дмитрий77Понимаете, автор того примера вроде как это и задумал, т.е. в среде VB берем ресурс из dll, а если exe, то вроде как из своего res, вы посмотрите код. Большинство примеров с vbaccelerator сильно перегружены шлаком и безбожно глючат, однако перед напильником ничто не устоит :)
Будет свободное время, обработаю.

Дмитрий77Почитав про всю эту жуть, взглянув на ваш tlbЭтот вариант я сам не понял, оно то работало, то нет, поэтому я и сомневался на его счет.

Дмитрий77Установка доп.набора элементов(основная) SetOurFramePosition hWndParentВот чтобы не плодить подобные простыни на чистом с++(на нем кода было бы раз в 5 больше), были придуманы шаблоны диалогов.

Jah loves you.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36494749
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyДмитрий77У меня VC2005 Express Edition, там кажется этого нет.
Если вы трепетно относитесь к легальности ПО, можете вроде бы ничего не нарушая установить клиентские компоненты от SQL Server 2005 версии Standart или выше, кусок от Visual Studio 2005, идущий в комплекте, умеет работать с файлами ресурсов наверняка.
Видите ли, я трепетно отношусь к своему VC++2005 Express Edition. Т.к. он в паре с SDK WIN2003 грамотно настроен на компиляцию тех C++ серьезных проектов (Open Source) кот. мне нужны и в кот. я разбираюсь. Поэтому дело не в трепетном отношении к легальности, а в нежелании эксперементировать с установкой чего-либо, что может "негативно повлиять".
Поэкспериментировать впринципе можно, но не на рабочей системе, а на другой. При этом думаю VC++6.0 для указанной цели вполне достаточно (причем я с 6.0 как бы знаком чуток), но можно и с "клиентские компоненты от SQL Server 2005 версии Standart или выше" или даже с полной версией новой студии, если таковая имеется в "нетрепетном" варианте, но не на основной рабочей машине.

Antonariy, коль такая пьянка и столько энергии потрачено, не взгляните в моем коде, одного момента понять не могу (брал то идею из примера конечно).

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Public gForm1 As Form
Public gFrameLabelPages As Frame 'содержит надпись Pages:
Public gTextPages As TextBox
...
    'Prepare the controls for CommonDialog
    Set gForm1 = New frmControls
    Set gFrameLabelPages = frmControls.FrameLabePages
    Set gCheckSplit = Nothing
...
    Set gFrameLabelFromTo = Nothing
    Unload frmControls
    Set gForm1 = Nothing

Не могу понять нафига эта gForm1 = New frmControls нужна и нужна ли.

Т.е. я якобы создаю новый экземпляр gForm1 из прототипа frmControls
и убиваю его в конце,

но при этом везде в коде обращаюсь к frmControls. , т.е. к оригиналу frmControls?

Причем добыть что-то типа gForm1.FrameLabePages я в принципе не могу.

Если убрать все строчки с gForm1, то все равно все работает точно также.

P.S. Запущено конечно, но все же хочу понять, нужна ли и зачем эта gForm1 = New frmControls.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36494862
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь она не нужна.

Чтобы понять что к чему, выполните код:
Код: plaintext
1.
2.
3.
4.
Sub Main()
 Dim frm As New Form1
 frm.Show
 Form1.Show
End Sub

Jah loves you.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36495319
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну все понятно.
И вот такой код работает.
Код: plaintext
1.
2.
3.
4.
5.
6.
Sub Main()
 Dim frm As New Form1
 frm.Show
 Form1.Show
 Form1.Command1.Caption = "form1"
 frm.Command1.Caption = "frm"
End Sub
Слегка непонятно почему в своем коде или в коде оригинала:
http://www.planet-source-code.com/Upload_PSC/ftp/CommonDial196237142006.zip

работает frmControls.FrameLabePages но не работает (по крайней мере vb это не предлагает после точки) gForm1.FrameLabePages

А то что она не нужна это я еще вчера подумал. Есть frmControls, с ней одной и работаем, куда их плодить то, диалог может быть только один в тек. момент.
Вот это надо
Код: plaintext
Unload frmControls
(во избежании несчастных случаев)
а gForm1 абсолютно ни при делах...
И в указанном оригинале она тоже не нужна кстати.
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36498604
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Слегка непонятно почему в своем коде или в коде оригинала:
>работает frmControls.FrameLabePages но не работает
>(по крайней мере vb это не предлагает после точки) gForm1.FrameLabePages

а, понятно, надо иногда не забывать писать
Option Explicit
в модуле
...глядишь какая константа неопределенно-потерянная всплывет...
...
Рейтинг: 0 / 0
В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
    #36503295
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77
> а, понятно, надо иногда не забывать писать
> Option Explicit
> в модуле
> ...глядишь какая константа неопределенно-потерянная всплывет...

Первые строки примера
и там-же я снимаю птицу Auto Syntax Check.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / В hook-нутом Common Control за-hook-нутые контролы не ловят Get Focus by TAB
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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