247 lines
6.6 KiB
C++
247 lines
6.6 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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<CBaseDialog*>(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);
|
|
}
|
|
|
|
|
|
|