|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|
SDIParentForm.Focus как в MDIParentForm08.11.2012, 19:01. Показов 2283. Ответов 17
Добрый день,
Вопрос чисто про WinAPI, но т.к. отдельного форума для него больше нет, пишу тут. Дело в том, что компилятор в котором я работаю не имеет MDI. Сама концепция MDI, на сколько я понимаю многим отличается от SDI. Таким образом, конвертировать уже созданную SDI в МDI не выйдет (ну, или нужна уйма работы). Вопрос, который меня интересует, это не связь ChildForm с ParentForm, а что в MDI, окна Child и Parent фокусированы одновременно (меня интересует только этот аспект). Если я всё правильно понимаю, в ОС одновременно может быть фокусировано только 1 окно. Если в МDI это возможно, выходит МDIParent и MDIChild каким-то образом являются одним целым?!... По умолчанию, все Child окна в моём компиляторе создаются с типом Overlapped (может иметь menu, controlbox... быть sizable и т.д. но подчиняется закрыванию и минимизации главного окна). Для симуляции MDI, Child окну я делаю SetParent на Handle компонента Panel который вклеен в MainForm. Всё работает, кроме фокуса! Как только фокусируется Child окно, MainForm теряет фокус и наоборот (когда фокусируется MainForm, Child окно теряет фокус)... Мне нужно сделать так, что бы при фокусировании Child окон, Parent окно не теряло фокус (Child окна между собой естественно будут терять фокус, и оно меня устаревает). Возможно ли это? Если да, то как, объясните пожалуйста (какие команды, инструкции и библиотеки нужны). Или это возможно только для MDI? Если только для MDI, возможно ли конвертировать уже созданную SDIParent в MDIParent и Child (Overlapped) v MDIChild? Заранее спасибо!
0
|
|
| 08.11.2012, 19:01 | |
|
Ответы с готовыми решениями:
17
Focus как можно узнать какое поле выбрано
|
|
Супер-модератор
|
|||||||
| 08.11.2012, 21:45 | |||||||
Поскольку WM_ACTIVATEAPP не приходит при смене активного окна в пределах одного приложения, то при активации дочернего окна визуально родительское будет также "активно".
1
|
|||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
||||||
| 09.11.2012, 00:06 [ТС] | ||||||
|
UI, не пашет...
Существует возможность "заблокировать" получениe WM_ACTIVATEAPP? (попытаюсь погуглить на этот счёт, может в MSDN нарою что-либо...)
0
|
||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
||
| 09.11.2012, 00:40 [ТС] | ||
|
После тестирования в Delphi (а после и в Коболе) стало ясно, что данное "лекарство" надо принимать главному окну прямо после открытия каждого дочернего окна. Однако, при нажатии на Titlebar главного окна (дочернее теряет фокус) и повторного фокусирования дочернего - лекарство уже не действует. Надо бы подумать, как автоматизировать данное дело ибо события LostFocus у окон нету...
0
|
||
|
Супер-модератор
|
||
| 09.11.2012, 01:00 | ||
|
0
|
||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|||||||||||||
| 09.11.2012, 01:26 [ТС] | |||||||||||||
Если говоря про функцию главного окна, Вы не имеете в виду FormCreate, то доступа к коду создания окна у меня нет (компилятор мой в стиле VB6, с ActiveX контролами). Какой выход Вы видите, если таковой существует? Вы говорили:
Ещё раз спсибо!
0
|
|||||||||||||
|
Супер-модератор
|
|||||||||||
| 09.11.2012, 01:38 | |||||||||||
|
Вообще-то речь шла о WinAPI (Дельфи запускать лень, приведу Сишный код). Само главное окно создается в WinMain с помощью CreateWindowEx, а функция его (обрабатывающая события) имеет вид:
Если нет доступа к чистому WinAPI - должен быть какой-то механизм обработки событий. В Дельфи это методы вот такого вида:
1
|
|||||||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|
| 09.11.2012, 02:11 [ТС] | |
|
UI, понятно! К сожалению в моём случае этот вариант невозможен:
Компилятор основан на ActiveX Controls, то есть уже скомпилированных компонентах. Таким образом, доступа к модификации кода их создания естественно нету. Но (!), как уже стало ясно (иначе я бы конечно не затеял эту дискуссию), всё так и есть возможность изменять параметры уже создавшихся объектов через WinAPI! На пример: В случае с ListView, с помощью SendMessage (GWL_EXSTYLE и LVM_SETEXTENDEDLISTVIEWSTYLE), я ставлю на True свойства LVS_EX_FULLROWSELECT, LVS_EX_HEADERDRAGDROP и т.д. То же самое с другими компонентами. В итоге, возможность изменять параметры через WinAPI есть, но те которые доступны уже после создания объекта а не при его создании... Добавлено через 5 минут П.С. Нам нужно что-то в стиле SetWindowProc/SetDefWindowProc, которое не существует... Однако, MSDN гласит о других на вид похожих функциях, в том числе CallWindowProc. Вопрос в том, существует ли функция изменяющая параметры DefWindowProc в WinMain? (надеюсь тут я не замутил страшную чушь )
0
|
|
|
Супер-модератор
|
||||||
| 09.11.2012, 02:34 | ||||||
|
Собственно, если можно просто заменить функцию окна на свою, используя SetWindowLongPtr + GWLP_WNDPROC - то это решило бы проблему. То есть, пишешь свой обработчик тех событий, которые нужны (в твоем случае - это WM_NCACTIVATE), а дальше (синтаксис Дельфи)
Всё опять упирается в возможности "чудо-компилятора"
1
|
||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
||
| 09.11.2012, 03:58 [ТС] | ||
|
1. Вызываю А:=GetWindowLongPtr(YourForm.Handle, GWLP_WNDPROC), таким образом у меня есть существующий обработчик событий. 2. Этот сохранённый обработчик событий (А) каким-то образом модифицирую на WM_NCACTIVATE = True (хотя как именно, с помощью какой функции - не понял). 3. Вызываю SetWindowLongPtr(YourForm.Handle, GWLP_WNDPROC, А) Правильно? Т.к. я коболист (даже не Дельфист, и уж темболее не УинАпист), не сочти за наглость, уж объясни и это, будь другом ![]() Добавлено через 1 час 5 минут Странное дело... В USER32.LIB нету функции GetWindowLongPtrA/GetWindowLongPtrW, только GetWindowLongA/GetWindowLongW
0
|
||
|
Супер-модератор
|
||||||||||||
| 09.11.2012, 10:30 | ||||||||||||
Сообщение было отмечено Kukstyler как решение
Решение
Уж извини, как в коболе будут выглядеть все эти приведения типов - не знаю, тут ничем помочь не смогу.
1
|
||||||||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|
| 10.11.2012, 05:04 [ТС] | |
|
Блин, весь день вожусь... Ничего! @MyWndProc если я не ошибаюсь означает, что это POINTER на процедуру MyWndProc. В коболе существует USAGE PROCEDURE-POINTER, но я им никогда не пользовался...
В общем, добился того, что компилятор не выдаёт ошибки, но программа не заводится... Теперь скомпилировал DLL-ку в другом компиляторе, (MicroFocus, он позволяет многое), и зову её через *.LIB в моём компиляторе - та же история... Могу скинуть DLL и LIB файлы, хотя я не знаю Дельфи может вызывать LIB-ом? CALL-CONVENTION в коболе иной чем STDCALL, по-этому пришлось делать такую фигню (кобол хорош тем, что читая его всё ясно), что может быть не так? DLL-кa: Код Delphi1 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 IDENTIFICATION DIVISION. PROGRAM-ID. MDI. special-names. call-convention 74 is WinAPI. *> WinApi = STDCALL DATA DIVISION. WORKING-STORAGE SECTION. 01 OldWndProc IS EXTERNAL PIC S9(9) COMP-5. 01 GWLP-WNDPROC PIC S9(9) COMP-5 VALUE -4. 01 WM-NCACTIVATE PIC S9(9) COMP-5 VALUE h"86". 77 MAIN-POINTER PROCEDURE-POINTER. 77 MDI-POINTER PROCEDURE-POINTER. LINKAGE SECTION. 01 lnk-hwnd PIC S9(9) COMP-5. 01 lnk-iMessage PIC 9(9) COMP-5. 01 lnk-wParam pic 9(9) comp-5. 01 lnk-lParam pic 9(9) comp-5. 01 mResult pic 9(9) comp-5. PROCEDURE DIVISION using lnk-hwnd lnk-iMessage lnk-wParam lnk-lParam mResult. SET MAIN-POINTER TO entry "MdiParent". CALL WinApi MAIN-POINTER USING lnk-hwnd lnk-iMessage lnk-wParam lnk-lParam mResult. goback. entry "MdiParent" WinApi using lnk-hwnd lnk-iMessage lnk-wParam lnk-lParam mResult. call WinAPI "GetWindowLongW" using by value lnk-hwnd by value GWLP-WNDPROC returning OldWndProc. set MDI-POINTER to entry "MyWndProc". call WinAPI "SetWindowLongW" using by value lnk-hwnd by value GWLP-WNDPROC by reference MDI-POINTER. EXIT PROGRAM. entry "MyWndProc". if lnk-wParam = WM-NCACTIVATE move -1 to lnk-wParam end-if call WinAPI "CallWindowProcW" using by value OldWndProc by value lnk-hwnd by value lnk-iMessage by value lnk-wParam by value lnk-lParam returning mResult exit program. MainForm.Opened: Код Delphi1 2 3 4 5 6 7 MOVE hwnMDIParent TO lnk-hwnd MOVE WM-NCACTIVATE TO lnk-iMessage CALL "MDI" USING lnk-hwnd lnk-iMessage lnk-wParam lnk-lParam mResult Добавлено через 1 час 21 минуту Разобрался с POINTER-ом. Всё сделал как ты говорил, однако: Если снять весь код с функции, то "ошибок нет", но окно рисуется ужасно и не имеет признаков жизни (выключаю через админ процессов). Дело в том, что если я ставлю STDCALL в функцию, то прога не компилируется, бранясь на то место где я ставлю POINTER на функцию (MainForm.obj : error LNK2001: unresolved external symbol _хххххх) А если я НЕ ставлю STDCALL в функцию, то окно рисуется наполовину, видать как раз подменить функцию удаётся, но так как она ничего не содержит (и она НЕ STDCALL), выдаётся такой результат. Блин, вот была бы у этих окон Event, типа GotFocus/LostFocus, проблема была бы решена ещё твоим первым предложением (DefWindowProc)...
0
|
|
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
||||||
| 08.10.2013, 15:31 [ТС] | ||||||
|
UI, достаточно продвинулся в данной теме.
И так на данный момент у меня есть pointer на старый WndProc (c помощью GetWindowLong) и своя функция MyWndProc (её pointer указан в SetWindowLong). Сама идея СабКлассинга реализована. Но возникают проблемы в функции MyWndProc - неправильно принимаются данные: Проблема в том, что функция MyWndProc принимает разные параметры (hwnd, message) только в одной из переменных - в HANDLE: В первом вызове MyWndProc, переменная HANDLE = 160 = 0х0084 то есть WM_NCACTIVATE. Во втором вызове (судя по всему не дожидаясь исполнения первого вызова до конца, чего я не очень понимаю) переменная HANDLE = handle окна. Только после этих двух вызовов вылезает MsgBox... Вроде SDTCALL тоже указан... В чём я могу ошибаться?
0
|
||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|
| 08.10.2013, 17:36 [ТС] | |
|
UI, Кстати, хотел ещё спросить: WndProc нужно 16 байт памяти или 20 байт (вместе с return value) ? То есть WndProc@16 или WndProc@20?
Благодарю за помощь.
0
|
|
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|||||||||||
| 09.10.2013, 23:59 [ТС] | |||||||||||
|
Картинка во вложениях из компилятора установленного на Win7 x64. В Win7 х86 - только один вызов (потом краш), информирована тлько переменная HWND и то со значением 0х86.
Ах да! Переменные приходиться обявлять в обратом порядке (что бы получить хотя бы что-то)! То есть не
0
|
|||||||||||
|
1260 / 870 / 268
Регистрация: 02.04.2009
Сообщений: 3,307
|
|
| 10.10.2013, 00:40 [ТС] | |
|
UI, ОК. Если добьюсь каких-либо результатов - напишу.
0
|
|
| 10.10.2013, 00:40 | |
|
Помогаю со студенческими работами здесь
18
Как убрать фокус (:focus) с изображения, при нажатии на него?
focus Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд.
Даже если у вас. . .
|
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает
монорепозиторий в котором находятся все исходники.
При создании нового решения, мы просто добавляем нужные проекты
и имеем. . .
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|