📄 dialogcontrol.hpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#pragma once
#ifndef __DIALOGCONTROL_HPP__
#define __DIALOGCONTROL_HPP__
#include <windows.h>
#include "Common.hpp"
#include "ControlDefinitions.h"
template <class Impl>
class DialogControl_t
{
//To use this control template you must define the following (or generate a compiler error)
// DialogWindowProc: Personal WndProc.
// Returns lresult to be returned to message-passer unless the Handled value is set to false
// LRESULT DialogWindowProc(
// UINT Message, //WndProc message
// WPARAM wParam, //Standard WPARAM
// LPARAM lParam, //Standard LPARAM
// bool& Handled //Was this message handled? If not, the internal dialog box procedure will be
// //called and the return value from this function ignored.
// );
public:
enum DialogType_e
{
dtModalDialog = 0,
dtModelessDialog,
};
private:
struct DialogHeader_t
{
DWORD m_TotalStructSize;
DWORD m_Flags;
VOID* pCallerParams;
};
public:
DialogControl_t()
{
m_hwnd = NULL;
}
DialogControl_t& operator=(HWND hwnd)
{
m_hwnd = hwnd;
return *this;
}
operator HWND()
{
return m_hwnd;
}
HRESULT
Create(
__in const WCHAR* pTemplateName,
HWND Parent,
DialogType_e Type,
__in_opt void* pParam,
__out void* pResult = NULL
)
{
if (IsWindow(m_hwnd))
{
ASSERT(0);
return E_FAIL;
}
if (!pTemplateName || !pResult || (Type > dtModelessDialog))
{
ASSERT(0);
return E_INVALIDARG;
}
HRESULT hr = S_OK;
union
{
int ReturnValue;
HWND Dialog;
} Result;
DialogHeader_t DummyParameters;
DummyParameters.m_TotalStructSize = sizeof(DialogHeader_t);
DummyParameters.m_Flags = (Type == dtModalDialog) ?
VDF_TYPE_MODAL : VDF_TYPE_MODELESS;
DummyParameters.pCallerParams = pParam;
m_Type = Type;
if (m_Type == dtModalDialog)
{
Result.ReturnValue = DialogBoxParam(
GlobalData_t::s_ModuleInstance,
pTemplateName,
Parent,
s_DialogWindowProc,
reinterpret_cast<LPARAM>(&DummyParameters)
);
if ((Result.ReturnValue == -1) || (Result.ReturnValue == ERROR_CANCELLED))
{
hr = CommonUtilities_t::GetErrorFromWin32();
}
else
{
*(reinterpret_cast<int*>(pResult)) = Result.ReturnValue;
}
}
else
{
ASSERT(m_Type == dtModelessDialog);
m_hwnd = CreateDialogParam(
GlobalData_t::s_ModuleInstance,
pTemplateName,
Parent,
s_DialogWindowProc,
reinterpret_cast<LPARAM>(&DummyParameters)
);
Result.Dialog = m_hwnd;
if (!Result.Dialog)
{
ASSERT(0);
hr = CommonUtilities_t::GetErrorFromWin32();
}
else
{
*(reinterpret_cast<HWND*>(pResult)) = Result.Dialog;
}
}
return hr;
}
//
// NOTE: Calling this function may delete the 'this' object.
// Do NOT use the object after calling this function.
//
HRESULT
End(
int Result = 0
)
{
HRESULT hr;
if (IsWindow(m_hwnd))
{
if (m_Type == dtModalDialog)
{
hr = EndDialog(m_hwnd, Result) ?
S_OK :
CommonUtilities_t::GetErrorFromWin32();
}
else
{
ASSERT(m_Type == dtModelessDialog);
HWND ToDestroy = m_hwnd;
m_hwnd = NULL;
//
// Note: DestroyWindow may end up deleting 'this'. Do
// not access any member variables after calling it.
//
hr = DestroyWindow(ToDestroy) ?
S_OK :
CommonUtilities_t::GetErrorFromWin32();
}
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE);
}
return hr;
}
//register the wnd class for this dialog
static
bool
Register(
)
{
WNDCLASS WindowClass = {0};
WindowClass.hInstance = GlobalData_t::s_ModuleInstance;
WindowClass.lpszClassName = Impl::GetWindowClassName();
WindowClass.lpfnWndProc = DefDlgProc;
WindowClass.cbWndExtra = DLGWINDOWEXTRA;
if ((RegisterClass(&WindowClass) == 0) &&
(GetLastError() != ERROR_CLASS_ALREADY_EXISTS))
{
return false;
}
return true;
}
static
void
Unregister(
)
{
UnregisterClass(
Impl::GetWindowClassName(),
GlobalData_t::s_ModuleInstance
);
return;
}
//public wnd proc for this class
static
BOOL
WINAPI
s_DialogWindowProc(
HWND hwnd,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
Impl* pThis = NULL;
if (Message == WM_INITDIALOG)
{
pThis = new Impl();
if (! pThis)
{
return EndDialog(hwnd, ERROR_CANCELLED);
}
//reset the last error to detect whether SetWindowLong succeeds or fails
SetLastError(0);
if ((SetWindowLong(hwnd, DWL_USER, reinterpret_cast<LONG>(pThis)) == 0) &&
(GetLastError() != 0))
{
//failure! - delete the object if necessary
delete pThis;
return EndDialog(hwnd, ERROR_CANCELLED);
}
//set the hwnd parameter of this dialog
pThis->m_hwnd = hwnd;
//set the type parameter of this dialog
pThis->m_Type = (reinterpret_cast<DialogHeader_t*>(lParam)->m_Flags & VDF_TYPE_MODELESS) ?
dtModelessDialog : dtModalDialog;
//reset the lparam for our caller
lParam = (LPARAM)reinterpret_cast<DialogHeader_t*>(lParam)->pCallerParams;
}
else
{
//otherwise, get the control from the window
pThis = reinterpret_cast<Impl*>(GetWindowLong(hwnd, DWL_USER));
}
LRESULT InternalReturnValue = 0;
BOOL ReturnValue = FALSE;
bool Handled = false;
//give the derived class a first crack at this message
if (pThis)
{
InternalReturnValue = pThis->DialogWindowProc(Message, wParam, lParam, Handled);
}
else
{
//Cannot process the message
return FALSE;
}
//if the derived class processed the message then set the desired return value
if (Handled)
{
switch (Message)
{
case WM_INITDIALOG:
//return value tells the system whether to set keyboard focus or not
ReturnValue = static_cast<BOOL>(InternalReturnValue);
break;
case WM_CTLCOLORLISTBOX:
//return value is a handle to a brush
ReturnValue = reinterpret_cast<BOOL>((HBRUSH)InternalReturnValue);
//especial case this message, since there is a bug in dialog manager
SetWindowLong(hwnd, DWL_MSGRESULT, InternalReturnValue);
break;
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC:
//return value is a handle to a brush
ReturnValue = reinterpret_cast<BOOL>((HBRUSH)InternalReturnValue);
break;
default:
//return TRUE indicating the message was processed
SetWindowLong(hwnd, DWL_MSGRESULT, InternalReturnValue);
ReturnValue = TRUE;
break;
}
}
//if the window has been destroyed, we need to delete the instance
if (Message == WM_DESTROY)
{
if (pThis)
{
delete pThis;
}
//clear the pointer out of the window
SetWindowLong(hwnd, DWL_USER, 0);
}
return ReturnValue;
}
protected:
HWND m_hwnd;
DialogType_e m_Type;
};
#endif //!defined __DIALOGCONTROL_HPP__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -