/****************************************************************************** Source File: Dialog.CPP Implements the CDialog class. See Dialog.H for class definitions and details Copyright (c) 1996 by Microsoft Corporation A Pretty Penny Enterprises Production Change History: 11-01-96 a-robkj@microsoft.com Created it 12-11-96 a-robkj@microsoft.com Implemented hook ******************************************************************************/ #include "ICMUI.H" // CDialog member functions // Class constructor- just save things, for now CDialog::CDialog(HINSTANCE hiWhere, int id, HWND hwndParent) { m_idMain = id; m_hwndParent = hwndParent; m_hiWhere = hiWhere; m_bIsModal = FALSE; m_hwnd = NULL; m_dpHook = NULL; m_lpHook = 0; } CDialog::CDialog(CDialog &cdOwner, int id) { m_idMain = id; m_hwndParent = cdOwner.m_hwnd; m_hiWhere = cdOwner.m_hiWhere; m_bIsModal = FALSE; m_hwnd = NULL; m_dpHook = NULL; m_lpHook = 0; } // Class destructor- clean up the window, if it is modeless. CDialog::~CDialog() { Destroy(); } // Modal Dialog Box LONG CDialog::DoModal() { m_bIsModal = TRUE; return (LONG)DialogBoxParam(m_hiWhere, MAKEINTRESOURCE(m_idMain), m_hwndParent, CDialog::DialogProc, (LPARAM) this); } // Modeless dialog box creation void CDialog::Create() { if (!m_bIsModal && m_hwnd) return; // We'va already got one! m_bIsModal = FALSE; CreateDialogParam(m_hiWhere, MAKEINTRESOURCE(m_idMain), m_hwndParent, CDialog::DialogProc, (LPARAM) this); } // Modeless dialog box destruction void CDialog::Destroy() { if (!m_bIsModal && m_hwnd) { DestroyWindow(m_hwnd); m_hwnd = NULL; } } // Dialog Procedure- this is a static private method. This means // that all instances of this class (including derived classes) share // this code (no pointers needed) and that only instances of this // class (not even derived classes) can find it. INT_PTR CALLBACK CDialog::DialogProc(HWND hwndMe, UINT uMsg, WPARAM wp, LPARAM lp) { CDialog *pcdMe = (CDialog *) GetWindowLongPtr(hwndMe, DWLP_USER); // If there is a hook procedure, it can either ignore or filter a // message by returning FALSE, or it can handle itself by returning // TRUE. WM_INITDALOG hook processing occurs AFTER all of our other // calls are made, and we allow the base class to define the LPARAM // that is passed in to the hook. // Because we do not have a pointer to the base class, we will miss // messages sent before WM_INITDIALOG (specifically WM_SETFONT) if (uMsg != WM_INITDIALOG && pcdMe && pcdMe -> m_dpHook && (*pcdMe -> m_dpHook)(hwndMe, uMsg, wp, lp)) return TRUE; switch (uMsg) { case WM_INITDIALOG: // The lp is the this pointer for the caller pcdMe = (CDialog *) lp; if(!pcdMe) { return FALSE; } SetWindowLongPtr(hwndMe, DWLP_USER, (LONG_PTR)pcdMe); pcdMe -> m_hwnd = hwndMe; // Derived classes override OnInit to initialize the dialog if (!pcdMe -> m_dpHook) return pcdMe -> OnInit(); else { // If there is a hook procedure, we will call that after the // override- if the override returned FALSE, so must we BOOL bReturn = pcdMe -> OnInit(); return (*pcdMe -> m_dpHook)(hwndMe, uMsg, wp, pcdMe -> m_lpHook) && bReturn; } case WM_COMMAND: if(pcdMe) { return pcdMe -> OnCommand(HIWORD(wp), LOWORD(wp), (HWND) lp); } break; case WM_NOTIFY: if(pcdMe) { return pcdMe -> OnNotify((int) wp, (LPNMHDR) lp); } break; case WM_HELP: if(pcdMe) { return pcdMe -> OnHelp((LPHELPINFO) lp); } break; case WM_CONTEXTMENU: if(pcdMe) { return pcdMe -> OnContextMenu((HWND) wp); } break; } return FALSE; } // Moves the window into position (needed to get dialogs positioned proeprly // in tab control display area). void CDialog::Adjust(RECT& rc) { SetWindowPos(m_hwnd, HWND_TOP, rc.left, rc.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_SHOWWINDOW); }