Пользовательская подсказка с диалогом WS_POPUP

Я хочу создавать собственные всплывающие подсказки, в которые можно поместить любые элементы управления. Я получил от CDialog и использовал WS_POPUP | WS_BORDERстили. Я также добавляю CS_DROPSHADOWстиль в OnInitDialog, чтобы получить тень всплывающей подсказки.

Тогда я управляю себя на WM_MOUSEHOVERи WM_MOUSELEAVEсобытия , чтобы показать / скрыть подсказки.

Я отображаю всплывающую подсказку с помощью SetWindowPosи, SWP_NOACTIVATEчтобы родитель не стал неактивным, а новый диалог стал активным. Но в любом случае, когда я создаю диалог, используя CDialog::Createметод ... главное окно становится неактивным ... что дает очень плохой эффект.

Таким образом, моя проблема заключается в том, как я могу создать CDialog со стилем WS_POPUP без моего главного окна (или родительского окна диалога), становящегося неактивным, когда появляется новый диалог ???

Спасибо за помощь!

Отредактировано: я не использую стиль WS_VISIBLE для создания диалога ... вот этот ресурс:

    IDD_LABEL_TOOLTIP_DLG DIALOGEX 0, 0, 100, 9
    STYLE DS_SETFONT | WS_POPUP | WS_BORDER
    FONT 8, "Tahoma", 0, 0, 0x0
    BEGIN
       LTEXT           "##################",IDC_TOOLTIP_LBL_TEXT,0,0,99,9
   END

Код, отображающий всплывающую подсказку, выглядит примерно так:

if(!pTooltipDlg)
{
    pTooltipDlg = new MyCustomTooltipDlg();
    pTooltipDlg->Create( MyCustomTooltipDlg::IDD, this);
}
pTooltipDlg->ShowWindow(SW_SHOWNOACTIVATE);

В первый раз (то есть, когда вызывается create) главные окна теряют фокус ... у остальных из них этот уродливый эффект не происходит ... поэтому я уверен, что это из-за Create.

12.12.2008 15:28:31
4 ОТВЕТА

Когда вы создаете свое окно, не устанавливайте на него флаг WS_VISIBLE. Затем вы можете использовать ShowWindow с SW_SHOWNA или SW_SHOWNOACTIVATE, чтобы сделать диалог видимым.

3
12.12.2008 15:35:27
Спасибо за вашу помощь! Теперь я использую ShowWindow (SW_SHOWNOACTIVATE) вместо SetWindowPos и ​​SWP_NOACTIVATE. Я не реализовал этот вариант, и он намного умнее. Плохо это все еще не работает ... Я отредактировал вопрос с некоторыми комментариями.
Javier De Pedro 12.12.2008 15:57:02

Вы звоните CDialog::Create()с WS_VISIBLEсетом? Может случиться так, что даже простого вызова Create()достаточно, чтобы отвлечь внимание от родителя. Может также стоить переопределить WM_SETFOCUSваш класс всплывающей подсказки и не вызывать базовый класс, чтобы фокус не мог изменить окна.

1
12.12.2008 15:37:29
Спасибо! Я тоже попробовал это. Я добавил эту запись карты ON_WM_SETFOCUS () в диалоговое окно всплывающей подсказки, но метод OnSetFocus даже не вызывается.
Javier De Pedro 12.12.2008 16:14:57

Прежде всего, рассмотрите возможность использования CWnd, а не CDialog. Это дает вам более тонкий контроль. И в любом случае вы не используете никаких функций CDialog, кроме шаблона диалога; это не так сложно динамически создавать ваши элементы управления.

Вы также можете рассмотреть в обработчиках сообщений обработку OnShowWindow и убедиться, что все команды show изменены на SW_SHOWNA, как в комментарии Марка Рэнсома.

Кроме того, в качестве всплывающей подсказки у него должно быть родительское окно NULL.

1
12.12.2008 16:28:10
Я предпочитаю не менять CDialog для CWnd, потому что я хочу иметь возможность использовать любой вид управления. В примере я только что использовал Label, но я хочу создать гораздо более сложные диалоги с ActiveX и т. Д. Я ценю два других предложения, но они не решают проблему. Спасибо, в любом случае!
Javier De Pedro 12.12.2008 23:09:09
РЕШЕНИЕ

Хорошо. Я наконец получил это! Я просто должен был вернуть FALSE в методе OnInitDialog, чтобы избежать активации диалога.

Всем спасибо!

0
13.12.2008 22:20:52