//----------------------------------------------------------------------------- // File: Dialog.cpp // Desc: Dialog class // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #include "wincontrol.h" #include "dialog.h" //----------------------------------------------------------------------------- // Name: ShowLastError // Description: Display the last error that was set. //----------------------------------------------------------------------------- void ShowLastError(HWND hwnd) { LPVOID lpMsgBuf; if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL )) { MessageBox( hwnd, (LPCWSTR)lpMsgBuf, L"Error", MB_OK | MB_ICONINFORMATION ); LocalFree( lpMsgBuf ); } } //----------------------------------------------------------------------------- // Name: CBaseDialog() // Desc: Constructor // // nID: Resource ID of the dialog //----------------------------------------------------------------------------- CBaseDialog::CBaseDialog(int nID) : m_nID(nID), m_hDlg(0), m_hinst(0), m_hwnd(0), m_NcTop(0), m_NcBottom(0), m_NcWidth(0) { } CBaseDialog::~CBaseDialog() { } //----------------------------------------------------------------------------- // Name: ShowDialog() // Desc: Displays the dialog // // hinst: Application instance // hwnd: Handle to the parent window. Use NULL if no parent. // // Returns TRUE if successful or FALSE otherwise //----------------------------------------------------------------------------- BOOL CBaseDialog::ShowDialog(HINSTANCE hinst, HWND hwnd) { // Cache these... m_hinst = hinst; m_hwnd = hwnd; // Show the dialog. Pass a pointer to ourselves as the LPARAM INT_PTR ret = DialogBoxParam(hinst, MAKEINTRESOURCE(m_nID), hwnd, DialogProc, (LPARAM)this); if (ret == 0 || ret == -1) { ShowLastError(NULL); return FALSE; } return (IDOK == ret); } //----------------------------------------------------------------------------- // Name: DialogProc() // Desc: DialogProc for the dialog. This is a static class method. // // lParam: Pointer to the CBaseDialog object. // // The CBaseDialog class specifies lParam when it calls DialogBoxParam. We store the // pointer as user data in the window. // // (Note: The DirectShow CBasePropertyPage class uses the same technique.) //----------------------------------------------------------------------------- INT_PTR CALLBACK CBaseDialog::DialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CBaseDialog *pDlg = 0; // Pointer to the dialog class that manages the dialog if (msg == WM_INITDIALOG) { // Get the pointer to the dialog object and store it in // the window's user data _SetWindowLongPtr(hDlg, DWLP_USER, lParam); pDlg = (CBaseDialog*)lParam; if (pDlg) { pDlg->m_hDlg = hDlg; pDlg->CalcNcSize(); HRESULT hr = pDlg->OnInitDialog(); if (FAILED(hr)) { pDlg->EndDialog(0); } } return FALSE; } // Get the dialog object from the window's user data pDlg = _GetWindowLongPtr(hDlg, DWLP_USER); if (pDlg != NULL) { switch (msg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: if (pDlg->OnOK()) { pDlg->EndDialog(IDOK); } return TRUE; case IDCANCEL: if (pDlg->OnCancel()) { pDlg->EndDialog(IDCANCEL); } return TRUE; default: return pDlg->OnCommand((HWND)lParam, LOWORD(wParam), HIWORD(wParam)); } break; case WM_NOTIFY: return pDlg->OnNotify((NMHDR*)lParam); default: return pDlg->OnReceiveMsg(msg, wParam, lParam); } } else { return FALSE; } } //----------------------------------------------------------------------------- // Name: CalcNcSize() // Desc: Calculate the non-client top, bottom, and width //----------------------------------------------------------------------------- void CBaseDialog::CalcNcSize() { LONG_PTR dwStyles = GetWindowLongPtr(m_hDlg, GWL_STYLE); m_NcTop = 0; m_NcBottom = 0; m_NcWidth = 0; if (dwStyles & WS_SIZEBOX) { m_NcTop += GetSystemMetrics(SM_CYSIZEFRAME); m_NcBottom += GetSystemMetrics(SM_CYSIZEFRAME); m_NcWidth += GetSystemMetrics(SM_CXSIZEFRAME); } else if (dwStyles & WS_BORDER) { m_NcTop += GetSystemMetrics(SM_CYBORDER); m_NcBottom += GetSystemMetrics(SM_CYBORDER); m_NcWidth += GetSystemMetrics(SM_CXBORDER); } if (dwStyles & WS_CAPTION) { m_NcTop += GetSystemMetrics(SM_CYCAPTION); } if (GetMenu(m_hDlg)) { m_NcTop += GetSystemMetrics(SM_CYMENU); } } //----------------------------------------------------------------------------- // Name: SetControlWindow // Desc: Associate a Control object with a control window. // // nID: Resource ID of the control //----------------------------------------------------------------------------- void CBaseDialog::SetControlWindow(Control& control, int nID) { control.SetWindow(GetDlgItem(nID)); } //----------------------------------------------------------------------------- // Name: RedrawControl() // Desc: Repaints a control // // nID: Resource ID of the control //----------------------------------------------------------------------------- void CBaseDialog::RedrawControl(int nID) { // Find the dialog rect and the control rect, both relative to the display RECT rcDlg, rcControl; GetWindowRect(m_hDlg, &rcDlg); GetWindowRect(GetDlgItem(nID), &rcControl); // Adjust the dialog rect by the size of the border and caption rcDlg.top += NonClientTop(); rcDlg.left += NonClientWidth(); // Find the dialog rect relative to the dialog position OffsetRect(&rcControl, - rcDlg.left, - rcDlg.top); InvalidateRect(m_hDlg, &rcControl, TRUE); UpdateWindow(m_hDlg); }