WM_NOTIFY и проблема сцепления суперкласса в Win32 - PullRequest
3 голосов
/ 17 апреля 2009

Для справки я использую метод суперкласса окна, описанный в этой статье. Конкретная проблема возникает, если я хочу обработать WM_NOTIFY сообщения (т. Е. Для пользовательского рисования) из базового элемента управления в суперклассе. Мне нужно либо отразить их обратно из родительского окна, либо установить свое собственное окно в качестве родительского (передается внутри CREATESTRUCT для WM_(NC)CREATE к базовому классу). Этот метод отлично работает, если у меня есть один суперкласс. Если я суперкласс мой суперкласс, то я столкнусь с проблемой. Теперь 3 WindowProc работают в одном и том же HWND, и когда я отражаю WM_NOTIFY сообщений (или отправляю их себе из вышеприведенного трюка выше), они всегда идут к самому внешнему (наиболее производному) WindowProc. Я не могу сказать, являются ли они сообщениями, предназначенными для внутреннего суперкласса (базовые сообщения должны идти в первый суперкласс), или сообщениями, предназначенными для внешнего суперкласса (сообщения от внутреннего суперкласса предназначены для внешнего суперкласса). Эти сообщения неразличимы, поскольку все они приходят от одного и того же HWND с одинаковым идентификатором элемента управления. Есть ли способ решить эту проблему, не создавая новое окно для инкапсуляции каждого уровня наследования?

Извините за стену текста. Это сложная концепция, чтобы объяснить. Вот диаграмма.

один суперкласс:

SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------/

суперкласс суперкласса:

SuperB::WindowProc() -> SuperA::WindowProc() -> Base::WindowProc()---\
             ^--------WM_NOTIFY(Base)--------+-----------------------/
             ^--------WM_NOTIFY(A)-----------/

Все сообщения WM_NOTIFY во втором случае поступают с одного и того же HWND и идентификатора управления, поэтому я не могу отличить сообщения, предназначенные для SuperA (от Base) и сообщения, предназначенные для SuperB (от SuperA). Есть идеи?

Ответы [ 2 ]

1 голос
/ 30 апреля 2010

Borland обошел это в VCL, изменив идентификатор сообщения на родительском уровне. Когда родительское окно получает сообщение WM_NOTIFY, идентификатор сообщения увеличивается на определенное смещение (CN_BASE), а затем сообщение передается непосредственно в дочернее окно, которое указано в сообщении. Затем процедура дочернего окна (и любые дочерние подклассы) может искать сообщения (CN_BASE + WM_NOTIFY) и иметь доступ к исходным данным WM_NOTIFY. Та же техника применима и к сообщениям WM_COMMAND. Попробуйте сделать что-то похожее в вашем коде.

1 голос
/ 05 декабря 2009

Естественно, элемент управления (оригинал?) Отправляет сообщения РОДИТЕЛЯМ. Предположительно, вы перехватываете их и отправляете обратно в исходный элемент управления. Внешний слой, конечно, сначала их увидит (а затем может просто передать их, если не захочет их обрабатывать).

Вы еще не сказали, какие сообщения NOTIFY вы хотите перехватить или почему. Но, поскольку теперь у вас есть контроль над ними в родительском процессе, чтобы отправить их обратно, почему бы просто не изменить сообщение. Сверните свою собственную структуру NMHDR, внедрите сообщение и данные и добавьте некоторую идентификацию для уровня суперкласса. В вашем суперклассе снимите те, которые вам нужны, переформатируйте те, которые вам не нужны, и отправьте их.

Звучит немного грязно. На этом уровне я был бы склонен вернуться к основам и создать свой собственный общий контроль (в зависимости, конечно, от того, что вы на самом деле пытаетесь сделать).

...