Здравствуйте, Kolesiki, Вы писали:
K>Мужики, есть старая, но по-прежнему интересная идея написать "свой GUI" для Винды. Причём это всё на D и для D.
Зачем?
K>Хочу изложить примерную схему для оценки (может и идею подкинете, как проще).
K>Основная идея — взять от Венды только примитивный элемент Window, а сами контролы полностью рисовать и обрабатывать самим (т.е. мы НЕ пользуемся стандартными Win32 BUTTON, COMBOBOX и т.п.)
Сразу минус — не нативно будет выглядеть.
K>Как и положено ООП либе, у нас будет базовый класс Widget, в котором будет находиться вся служебная фигня, нужная венде.
Перепиши Qt на D и успокойся
K>В Widget будет так же лежать своя (перегружабельная) WindowProc для обработки виндовых сообщений.
K>Как и положено, мы будем RegisterClass для всех наших виджетов и затем их CreateWindow.
K>И вот тут возникает засада, известная всем кульхацкерам: для RegisterClass нужен адрес обработчика сообщений (WindowProc), который в нашей либе... инстанс метод!
K>Шахматисты из Borland (да и в MFC тот же хак) решили эту задачу каким-то хитрым ассемблером, чтобы винда сама вызывала нужный метод нужного класса через манипуляцию стеком. Увы, в D я не знаю кишок и не смогу нахакать такой вызов.
Как MFC/WTL и Borland решает эту задачу — не помню. В MFC вроде есть словарь/map.
K>Но почесать левое ухо правой рукой всё же можно: завести одну глобальную функцию WindowProc (вне всех классов) и зарегать её для всех виджетов. А уже ей параметром придёт хэндл hWnd любого нашего окна. А далее из глобального же Dictionary мы по hWnd достаём объект Widget, у которого и вызовем инстансную WindowProc.
K>Кратко: RegisterClass("любой виджет", ГлобальнаяWindowProc). ГлобальнаяWindowProc принимает ВСЕ сообщения приложения, а далее диспетчеризует по объектам.
K>Тут сложность в том, что придётся внимательно следить, чтобы этот Dictionary всегда был актуален — вовремя добавлять/убирать оттуда хэндлы, да ещё всё это в многопоточной среде.
Я в свое время в своей либе делал просто — CreateWindow получает пользовательский аргумент, который передает в WindowProc, вот там я и передавал указатель на объект. Глобальная static WindowProc просто кастила к базовуму Window и вызывала виртуальную WindowProc объекта. А если нужно пользовательские данные передавать — так в объекте пожалуйста.
K>А ещё маленький подвопрос: после GetMessage обязательно делать DispatchMessage или я сам могу раскидать структуру MSG по нужным объектам?
Можешь попробовать, но устанешь повторять логику DispatchMessage, ну или твои окна будут совсем неадекватно себя вести.
K>В общем, идея не новая, но не хочется наступать на пройденные грабли — может кто подкинет совет.
Хочешь совет? Ляг, поспи, может пройдет.
K>PS
K>Никакие Qt/GTk не хочу. DLangUI — тем более.
Тебе сколько лет? Если 20 — то да, можно выкинуть несколько лет на это, опыта наберешься. Если за 30 уже — лучше не трать время, а заведи семью