📄 dialogscreen.cpp
字号:
//
// 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.
//
#include "DialogScreen.hpp"
#include "Common.hpp"
#include "Controls.hpp"
#include "Debug.hpp"
#include "Layout.hpp"
#include "Resource.h"
#include "Input.hpp"
//default to 250 ms timeout for WM_TIMER messages...
const UINT c_TimeOutValue = 250;
//arbitrary timer id for this window
const UINT c_TimerIdentifier = 20;
EXTERN_C
BOOL
WINAPI
PHDialogScreen(
PH_DIALOG_SCREEN_PARAMETERS* pParameters
)
{
if (!pParameters ||
(pParameters->StructSize != sizeof(PH_DIALOG_SCREEN_PARAMETERS)) ||
(!pParameters->Instance && (
(0 == HIWORD(pParameters->pTitle)) ||
(pParameters->MenuId))
)
)
{
ASSERT(0);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
DialogScreen_t DialogScreen;
HRESULT hr;
hr = DialogScreen.Create(
MAKEINTRESOURCE(IDD_DIALOG_SCREEN),
pParameters->Owner,
(pParameters->Flags & VDF_TYPE_MODELESS) ?
DialogScreen_t::dtModelessDialog :
DialogScreen_t::dtModalDialog,
pParameters,
&pParameters->result.SelectedId
);
return TRUE;
}
/*------------------------------------------------------------------------------
DialogScreen_t::DialogScreen_t
Constructor
------------------------------------------------------------------------------*/
DialogScreen_t::DialogScreen_t(
)
{
TRACE(ZONE_COMMON_CTOR);
m_pHookProc = NULL;
m_pUserData = NULL;
m_State = 0;
m_TimerId = 0;
m_InputPanelVisible = false;
}
/*------------------------------------------------------------------------------
DialogScreen_t::~DialogScreen_t
Destructor
------------------------------------------------------------------------------*/
DialogScreen_t::~DialogScreen_t(
)
{
TRACE(ZONE_COMMON_CTOR);
ASSERT(! m_TimerId);
}
/*------------------------------------------------------------------------------
DialogScreen_t::GetWindowClassName
WndClassName for this dialog
------------------------------------------------------------------------------*/
const WCHAR*
DialogScreen_t::GetWindowClassName(
void
)
{
return WNDCLASS_DIALOGSCREEN;
}
/*------------------------------------------------------------------------------
DialogScreen_t::DialogWindowProc
WndProc for this dialog
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::DialogWindowProc(
UINT Message,
WPARAM wParam,
LPARAM lParam,
bool& Handled
)
{
//by default assume we handled the message
Handled = true;
if (Message != WM_INITDIALOG)
{
LRESULT Result = CallHook(Message, wParam, lParam);
if (Result)
{
return Result;
}
}
switch (Message)
{
case WM_ACTIVATE:
if (LOWORD(wParam) != WA_INACTIVE)
{
SetFocus(m_hwnd);
}
return 0;
case WM_COMMON_GET_INPUT_PANEL_STATUS:
return m_InputPanelVisible;
case WM_COMMON_SET_INPUT_PANEL_STATUS:
m_InputPanelVisible = (wParam != 0);
return 0;
case WM_CTLCOLORLISTBOX:
if (GlobalData_t::s_ListBoxBrush == NULL)
{
GlobalData_t::s_ListBoxBrush = CreateSolidBrush(Colors_t::ListBoxBackgroundColor());
ASSERT(GlobalData_t::s_ListBoxBrush);
}
return reinterpret_cast<LRESULT>(GlobalData_t::s_ListBoxBrush);
case WM_DELETEITEM:
case WM_DRAWITEM:
case WM_MEASUREITEM:
return ReflectOwnerDrawMessage(Message, wParam, lParam);
case WM_COMMAND:
return OnCommand(
LOWORD(wParam),
HIWORD(wParam),
reinterpret_cast<HWND>(lParam)
);
case WM_ERASEBKGND:
return OnEraseBkgnd(reinterpret_cast<HDC>(wParam), lParam);
case WM_HELP:
//forward WM_HELP messages to the owner
SendMessage(m_Owner, Message, reinterpret_cast<WPARAM>(m_hwnd), NULL);
return TRUE;
case WM_INITDIALOG:
return OnInitDialog(
reinterpret_cast<HWND>(wParam),
reinterpret_cast<PH_DIALOG_SCREEN_PARAMETERS*>(lParam)
);
case WM_LBUTTONDOWN:
if (OnLButtonDown(wParam, LOWORD(lParam), HIWORD(lParam)))
{
Handled = false;
}
return 0;
case WM_NOTIFY:
return OnNotify(wParam, reinterpret_cast<NMHDR*>(lParam));
case WM_PAINT:
return OnPaint(reinterpret_cast<HDC>(wParam));
case WM_SETFOCUS:
return OnSetFocus(reinterpret_cast<HWND>(wParam));
case WM_SETTINGCHANGE:
Input_HandleEvent(
Input_t::ieWMSettingChanged,
reinterpret_cast<Input_t::IPARAM>(wParam)
);
//forward WM_SETTINGCHANGE messages to the listbox
SendDlgItemMessage(m_hwnd, IDC_LISTBOX, Message, wParam, lParam);
Handled = false;
return 0;
case WM_TIMER:
return OnTimer();
case WM_DESTROY:
if (m_TimerId)
{
KillTimer(m_hwnd, m_TimerId);
m_TimerId = 0;
}
return 0;
default:
Handled = false;
return 0;
}
}
/*------------------------------------------------------------------------------
DialogScreen_t::CallHook
Call the hook procedure if available
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::CallHook(
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
if (!m_pHookProc)
{
return 0;
}
return m_pHookProc(m_hwnd, Message, wParam, lParam, m_pUserData);
}
/*------------------------------------------------------------------------------
DialogScreen_t::CheckState
Determines if a given state is currently set
------------------------------------------------------------------------------*/
inline
bool
DialogScreen_t::CheckState(
DWORD State,
const DWORD* pToCheckAgainst
) const
{
if (!pToCheckAgainst)
{
pToCheckAgainst = &m_State;
}
return ((*pToCheckAgainst & State) == State);
}
/*------------------------------------------------------------------------------
DialogScreen_t::GetScrollUpRect
Gets the rectangle for the scroll-up arrow
------------------------------------------------------------------------------*/
void
DialogScreen_t::GetScrollUpRect(
RECT& ScrollUpRectangle
)
{
GetClientRect(m_hwnd, &ScrollUpRectangle);
ScrollUpRectangle.right -= Layout_t::DialogScreenScrollArrowRightMargin();
ScrollUpRectangle.left = ScrollUpRectangle.right - Layout_t::DialogScreenScrollArrowWidth();
ScrollUpRectangle.top += Layout_t::DialogScreenScrollArrowTopMargin();
ScrollUpRectangle.bottom = ScrollUpRectangle.top + Layout_t::DialogScreenScrollArrowHeight();
}
/*------------------------------------------------------------------------------
DialogScreen_t::GetScrollDownRect
Gets the rectangle for the scroll-down arrow
------------------------------------------------------------------------------*/
void
DialogScreen_t::GetScrollDownRect(
RECT& ScrollDownRectangle
)
{
GetClientRect(m_hwnd, &ScrollDownRectangle);
ScrollDownRectangle.right -= Layout_t::DialogScreenScrollArrowRightMargin();
ScrollDownRectangle.left = ScrollDownRectangle.right - Layout_t::DialogScreenScrollArrowWidth();
ScrollDownRectangle.bottom -= Layout_t::DialogScreenScrollArrowBottomMargin();
ScrollDownRectangle.top = ScrollDownRectangle.bottom - Layout_t::DialogScreenScrollArrowHeight();
}
/*------------------------------------------------------------------------------
DialogScreen_t::GetTitleRect
Gets the rectangle for the title of screen
------------------------------------------------------------------------------*/
void
DialogScreen_t::GetTitleRect(
RECT& TitleRect
)
{
GetClientRect(m_hwnd, &TitleRect);
TitleRect.left = Layout_t::DialogScreenTitleLeftMargin();
TitleRect.top = Layout_t::DialogScreenTitleTopMargin();
TitleRect.right = TitleRect.right - Layout_t::DialogScreenTitleRightMargin();
TitleRect.bottom = Layout_t::DialogScreenTitleTopMargin() + Layout_t::DialogScreenTitleHeight();
}
/*------------------------------------------------------------------------------
DialogScreen_t::ReflectOwnerDrawMessage
Forwards owner draw messages to the listbox
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::ReflectOwnerDrawMessage(
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
return SendDlgItemMessage(m_hwnd, IDC_LISTBOX, Message, wParam, lParam);
}
/*------------------------------------------------------------------------------
DialogScreen_t::OnCommand
Handle command messages (notifies owner)
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::OnCommand(
WORD CommandId,
WORD NotifyCode,
HWND Control
)
{
if ((m_Type == dtModalDialog) &&
(CommonUtilities_t::ControlTypeMenuButton == CommonUtilities_t::GetControlType(Control)))
{
End(CommandId);
return 0;
}
NMHDR nmhdr;
nmhdr.hwndFrom = Control;
nmhdr.idFrom = GetWindowLong(Control, GWL_ID);
nmhdr.code = NotifyCode;
SendMessage(m_Owner, WM_NOTIFY, CommandId, (LPARAM)&nmhdr);
return 0;
}
/*------------------------------------------------------------------------------
DialogScreen_t::OnEraseBkgnd
Handle erase background
NOTE: By default it paints on back buffer (delayed paint). This method
uses lParam as a workaround to request paint into the device context.
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::OnEraseBkgnd(
HDC hdc,
LPARAM lParam
)
{
HRESULT hr;
PaintHelper_t paint;
hr = paint.Attach(hdc);
ASSERT(SUCCEEDED(hr));
RECT ClientRect;
GetClientRect(m_hwnd, &ClientRect);
if ((HDC)m_BackBuffer == NULL)
{
hr = m_BackBuffer.CreateCanvas(
m_hwnd,
ClientRect.right,
ClientRect.bottom
);
ASSERT(SUCCEEDED(hr));
}
//use lParam as a workaround to request immediate paint
PaintHelper_t& paintToUse = (lParam || ((HDC)m_BackBuffer == NULL)) ? paint : m_BackBuffer;
PHDrawBackground(paintToUse, &ClientRect);
return 1;
}
/*------------------------------------------------------------------------------
DialogScreen_t::OnInitDialog
Handle initialization for the dialog screen
------------------------------------------------------------------------------*/
LRESULT
DialogScreen_t::OnInitDialog(
HWND ControlToReceiveFocus,
PH_DIALOG_SCREEN_PARAMETERS* pParameters
)
{
//return value tells the system to set or not the keyboard focus
if (!pParameters)
{
ASSERT(0);
SetLastError(ERROR_INVALID_PARAMETER);
return End(ERROR_CANCELLED);
}
m_pParameters = pParameters;
m_Owner = pParameters->Owner;
m_Instance = pParameters->Instance;
m_pHookProc = pParameters->pDialogHook;
m_pUserData = pParameters->pUserData;
//set identifier for this dialog window
SetWindowLong(m_hwnd, GWL_ID, pParameters->Id);
if (0 == HIWORD(pParameters->pTitle))
{
SetWindowTextW(
m_hwnd,
CommonUtilities_t::LoadString(m_Instance, LOWORD(pParameters->pTitle))
);
}
else
{
SetWindowTextW(m_hwnd, pParameters->pTitle);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -