FindWindow по имени класса не работает? - PullRequest
0 голосов
/ 26 августа 2011

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

Я подумал, что самый простой способ сделать это - зарегистрировать класс следующим образом:

    // for CWnd::FindWindow
    WNDCLASS wndcls;
    SecureZeroMemory(&wndcls, sizeof(WNDCLASS));
    wndcls.lpszClassName    = L"CTransactionDialog";
    wndcls.style            = CS_HREDRAW | CS_VREDRAW;
    wndcls.lpfnWndProc      = AfxWndProc;
    wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
    wndcls.hInstance        = AfxGetInstanceHandle();
    wndcls.hIcon            = NULL;
#ifndef _WIN32_WCE_NO_CURSOR
    wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
#else
    wndcls.hCursor          = 0;
#endif
    wndcls.hbrBackground    = (HBRUSH) (COLOR_BACKGROUND + 1);
    wndcls.lpszMenuName     = NULL;

    BOOL retVal = AfxRegisterClass(&wndcls);
    if (!retVal)
        AfxMessageBox(L"AfxRegisterClass(CTransactionDialog) Failed");

Затем в ответ на различные обработчики событий и сообщения, где я хотел бы, чтобы эти немодальные окна или окна были закрыты, чтобы сделать что-то простое, как это:

CWnd* pFound = NULL;
while ((pFound = CWnd::FindWindow(L"CTransactionDialog", NULL)) != NULL)
    pFound->DestroyWindow();

Однако, несмотря на успешную регистрацию класса и просмотр GetRuntimeClass рассматриваемого диалогового окна при отладке и обнаружение, что оно совпадает с ожидаемым, FindWindow никогда не находит или не закрывает эти немодальные диалоговые окна, как ожидалось.

Что я делаю не так или есть лучший способ сделать это?

Обновление: Так создается диалог с помощью статического метода в классе диалога. У ресурса диалога для идентификатора, указанного в create, установлено свойство Popup, которое должно соответствовать стилю WS_POPUP под обложками MFC. Насколько мне известно, в диалоге не должно быть и не должно быть родителя.

CTransactionDialog* CTransactionDialog::ShowTransactionDialog(const CRect& crCtrlToFloatAbove, UINT dialogID, Itime defaultTime, Itime initialTime)
{
    CTransactionDialog* pCTDialog = new CTransactionDialog(crCtrlToFloatAbove, dialogID, defaultTime, initialTime);
    pCTDialog->Create(CTransactionDialog::IDD);
    pCTDialog->ShowWindow(SW_SHOW);

    return pCTDialog;
}

Обновление: Дох! FindWindowEx тоже ничего не находит.

CWnd::FindWindowEx(AfxGetMainWnd()->GetSafeHwnd(), NULL, L"CTransactionDialog", NULL);

Однако у меня есть новый план. Я просто собираюсь сделать свое собственное оконное сообщение и обработать его в основном фрейме. Я думаю, что смогу обойтись без передачи указателя на диалоговое окно в качестве lParam сообщения, а затем приведение его к CWnd* с последующим вызовом DestroyWindow. В большинстве случаев это будет работать очень по-разному. У меня могут возникнуть проблемы с минимизацией и максимизацией основного окна фрейма для диалогов, в которых ничто не удерживает указатель, но мы увидим.

Ответы [ 5 ]

4 голосов
/ 26 августа 2011

FindWindow не работает с дочерними окнами.Чтобы найти дочернее окно, вы можете использовать FindWindowEx, передавая HWND родительского окна в качестве первого параметра.

1 голос
/ 26 августа 2011

Имя класса обозначает НЕ имя класса c ++ - оно обозначает имя класса окна.Это имя использовалось для регистрации окна операционной системой и не имеет ничего общего с классом c ++.

Может MSDN Просветите вас ...

0 голосов
/ 16 марта 2016

Не уверен на 100% в этом, но я думаю, что вам нужно установить имя вашего класса в файле ресурсов. Вы определяете класс Windows и создаете класс диалога, но не связываете их. Установка имени класса в структуре WNDCLASS не поможет, если у вас нет способа связать его с диалогом. Если вы используете файл ресурсов и задаете диалоговое окно и имя класса, тогда оно должно работать.

0 голосов
/ 13 октября 2011

Ниже приведено самое простое и чистое решение, которое я смог придумать:

BOOL CTransactionDialog::OnNcActivate(BOOL bActive)
{
    if (!bActive)
        PostMessage(WM_CLOSE);

    return CDialog::OnNcActivate(bActive);
}
0 голосов
/ 26 августа 2011

CWnd :: FindWindow не выполняет поиск дочерних окон.

Возможно ли, что создаваемое вами окно без режима имеет родительский набор, и именно поэтому FindWindow его не находит?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...