/* * CiderPress * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * See the file LICENSE for distribution terms. */ /* * Trivial implementation of a modeless dialog box. */ #ifndef UTIL_MODELESS_H #define UTIL_MODELESS_H /* * This class must be allocated on the heap, and destroyed by calling * DestroyWindow(). Do not delete the object or call EndDialog(). * * To use, call Create(dialogID, pParentWnd). Make sure "visible" is set to * "true" in the dialog properties. * * For "progress" dialogs: immediately before creating the window with Create, * disable the main window with EnableWindow(FALSE). That prevents it from * getting user input. When you're done, re-enable it with * EnableWindow(TRUE), and then DestroyWindow on this object. (If you do it * the other way, some other window will get focus, and you have to use * SetActiveWindow() to get it back... but that causes a UI flash.) This * behavior is now implemented in ExclusiveModelessDialog. */ class ModelessDialog : public CDialog { public: ModelessDialog(void) : fOkayToDelete(false) {} virtual ~ModelessDialog(void) { ASSERT(fOkayToDelete); } /* * OK button clicked. Must override to prevent standard EndDialog * behavior. */ virtual void OnOK(void) override { if (UpdateData() != FALSE) // try the DDX/DDV stuff, if any DestroyWindow(); } /* * ESC key hit or Cancel button clicked. Must override to prevent * standard EndDialog behavior. */ virtual void OnCancel(void) override { DestroyWindow(); } protected: void PostNcDestroy(void) override { // this may not arrive immediately fOkayToDelete = true; delete this; } private: DECLARE_COPY_AND_OPEQ(ModelessDialog) bool fOkayToDelete; // sanity check }; /* * Variant of ModelessDialog that handles enabling and disabling the parent * window. */ class ExclusiveModelessDialog : public ModelessDialog { public: ExclusiveModelessDialog(void) : fpParentWnd(NULL) {} virtual ~ExclusiveModelessDialog(void) {}; /* disable the parent window before we're created */ BOOL Create(int dialogID, CWnd* pParentWnd = NULL) { ASSERT(pParentWnd != NULL); // else what's the point? if (pParentWnd != NULL) { fpParentWnd = pParentWnd; fpParentWnd->EnableWindow(FALSE); } return ModelessDialog::Create(dialogID, pParentWnd); } /* enable the parent window before we're destroyed */ virtual BOOL DestroyWindow(void) override { if (fpParentWnd != NULL) fpParentWnd->EnableWindow(TRUE); return ModelessDialog::DestroyWindow(); } private: DECLARE_COPY_AND_OPEQ(ExclusiveModelessDialog) CWnd* fpParentWnd; }; /* From DLGCORE.CPP line 516: // disable parent (before creating dialog) HWND hWndParent = PreModal(); // ATM: finds parent of modal dlg AfxUnhookWindowCreate(); BOOL bEnableParent = FALSE; if (hWndParent != NULL && ::IsWindowEnabled(hWndParent)) { ::EnableWindow(hWndParent, FALSE); bEnableParent = TRUE; } [...] if (bEnableParent) ::EnableWindow(hWndParent, TRUE); if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd) ::SetActiveWindow(hWndParent); // destroy modal window DestroyWindow(); PostModal(); */ #endif /*UTIL_MODELESS_H*/