📄 menuscreen.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 "MenuScreen.hpp"
#include "Common.hpp"
#include "Controls.hpp"
#include "Debug.hpp"
#include "Layout.hpp"
#include "Resource.h"
#include <intsafe.h>
//forward declarations
BOOL
CALLBACK
MenuHookProc(
HWND hwnd,
UINT Message,
WPARAM wParam,
LPARAM lParam,
void* pvParam
);
VOID
EndMenu(
HWND Menu,
int Result,
PH_MENU_SCREEN_PARAMETERS* pParams
);
/*------------------------------------------------------------------------------
PHMenuScreen
Exposed through phcommon API. Creates a specific menu screen.
Parameters:
pParameters: parameters specific to this menu screen
Returns (BOOL): indicating success or failure
------------------------------------------------------------------------------*/
EXTERN_C
BOOL
WINAPI
PHMenuScreen(
PH_MENU_SCREEN_PARAMETERS* pParameters
)
{
if (!pParameters ||
(pParameters->StructSize != sizeof(PH_MENU_SCREEN_PARAMETERS)) ||
!pParameters->Instance ||
(pParameters->ItemCount < 0) ||
((pParameters->Flags & VDF_TYPE_MODELESS) && !pParameters->NotificationMsg)
)
{
ASSERT(0);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//We need to clone the input parameters -
//determine how much memory to allocate for the items
UINT ItemsSize;
if (FAILED(UIntMult(pParameters->ItemCount, sizeof(PHMS_ITEM), &ItemsSize)))
{
SetLastError(ERROR_ARITHMETIC_OVERFLOW);
return FALSE;
}
PHMS_ITEM* pCopyItems = NULL;
PH_MENU_SCREEN_PARAMETERS* pCloneParameters = NULL;
PH_DIALOG_SCREEN_PARAMETERS DialogParameters = {0};
BOOL RetVal = FALSE;
//first clone the items
pCopyItems = reinterpret_cast<PHMS_ITEM*>(TrackAlloc(ItemsSize));
if (! pCopyItems)
{
SetLastError(ERROR_OUTOFMEMORY);
goto cleanup;
}
memcpy(pCopyItems, pParameters->pMenuScreenItems, ItemsSize);
//next clone the parameters
pCloneParameters = reinterpret_cast<PH_MENU_SCREEN_PARAMETERS*>(TrackAlloc(sizeof(PH_MENU_SCREEN_PARAMETERS)));
if (! pCloneParameters)
{
SetLastError(ERROR_OUTOFMEMORY);
goto cleanup;
}
memcpy(pCloneParameters, pParameters, sizeof(PH_MENU_SCREEN_PARAMETERS));
//add the cloned items into the cloned parameters
pCloneParameters->pMenuScreenItems = pCopyItems;
//setup the dialog struct
DialogParameters.StructSize = sizeof(DialogParameters);
DialogParameters.Flags = pParameters->Flags;
DialogParameters.Owner = pParameters->Owner;
DialogParameters.Id = pParameters->Id;
DialogParameters.Instance = GlobalData_t::s_ModuleInstance;
DialogParameters.pStatusHeader = MAKEINTRESOURCE(IDS_MENU_SCREEN_HEADER);
if (pParameters->pTitle)
{
if (0 == HIWORD(pParameters->pTitle))
{
DialogParameters.pTitle = CommonUtilities_t::LoadString(
pParameters->Instance,
LOWORD(pParameters->pTitle)
);
}
else
{
DialogParameters.pTitle = pParameters->pTitle;
}
}
else
{
DialogParameters.pTitle = MAKEINTRESOURCE(IDS_MENU_SCREEN_TITLE);
}
DialogParameters.MenuId = IDMB_MENU_SCREEN;
DialogParameters.pDialogHook = MenuHookProc;
DialogParameters.pUserData = pCloneParameters;
if (! PHDialogScreen(&DialogParameters))
{
//failed! - cleanup and exit
goto cleanup;
}
if (pParameters->Flags & VDF_TYPE_MODELESS)
{
//The dialog is responsible for freeing the allocated structure on exit
pParameters->result.Dialog = DialogParameters.result.Dialog;
return TRUE;
}
//otherwise, this was a modal dialog, set the return value and cleanup
ASSERT(!(pParameters->Flags & VDF_TYPE_MODELESS));
pParameters->result.SelectedId = pCloneParameters->result.SelectedId;
RetVal = TRUE;
cleanup:
if (pCopyItems)
{
TrackFree(pCopyItems);
}
if (pCloneParameters)
{
TrackFree(pCloneParameters);
}
return RetVal;
}
/*------------------------------------------------------------------------------
MenuHookProc
Hook proc that handles messages specific to this dialog
------------------------------------------------------------------------------*/
BOOL
CALLBACK
MenuHookProc(
HWND hwnd,
UINT Message,
WPARAM wParam,
LPARAM lParam,
void* pvParam
)
{
if (! pvParam)
{
ASSERT(FALSE);
return FALSE;
}
PH_MENU_SCREEN_PARAMETERS* pParameters =
reinterpret_cast<PH_MENU_SCREEN_PARAMETERS*>(pvParam);
switch (Message)
{
case WM_INITDIALOG:
//on init dialog setup the listbox and the status region
if (pParameters->ItemCount)
{
ListBox_t ListBox;
ListBox = GetDlgItem(hwnd, IDC_LISTBOX);
//add each item to the listbox
for (int i = 0; i < pParameters->ItemCount; i++)
{
IVoIPDisplayItem* pItem = NULL;
HRESULT hr = PHCreateTextDisplayItem(
CommonUtilities_t::LoadString(
pParameters->Instance,
pParameters->pMenuScreenItems[i].StringId
),
&pItem
);
if (FAILED(hr))
{
ASSERT(FALSE);
EndMenu(hwnd, 0, pParameters);
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
ListBox.AddItem(-1, pItem);
}
//select first item by default
SendMessage(ListBox, LB_SETCURSEL, 0, 0);
SetFocus(ListBox);
}
return FALSE;
case WM_DESTROY:
//when we destroy the modeless dialog, cleanup the memory allocated in PHMenuScreen
if (pParameters->Flags & VDF_TYPE_MODELESS)
{
TrackFree(pParameters->pMenuScreenItems);
TrackFree(pParameters);
}
break;
case WM_COMMAND:
//if the user selected OK or double clicked on an item in the listbox,
//return from this dialog
if (LOWORD(wParam) == IDOK || (HIWORD(wParam) == LBN_DBLCLK && LOWORD(wParam) == IDC_LISTBOX))
{
ListBox_t listbox;
listbox = GetDlgItem(hwnd, IDC_LISTBOX);
int CurrentSel = SendMessage(listbox, LB_GETCURSEL, 0, 0);
if (CurrentSel >= 0 && CurrentSel < pParameters->ItemCount)
{
EndMenu(hwnd, pParameters->pMenuScreenItems[CurrentSel].Identifier, pParameters);
}
return TRUE;
}
//if the user selected cancel, cancel out of the dialog
if (LOWORD(wParam) == IDCANCEL)
{
EndMenu(hwnd, PHMENU_CANCELLED, pParameters);
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
/*------------------------------------------------------------------------------
EndMenu
End this dialog screen.
Parameters:
Menu: The menu screen to end
Result: The result to return to the caller
pParameters: Parameters related to starting/ending the dialog
------------------------------------------------------------------------------*/
VOID
EndMenu(
HWND Menu,
int Result,
PH_MENU_SCREEN_PARAMETERS* pParameters
)
{
if (! pParameters)
{
ASSERT(FALSE);
return;
}
if (!(pParameters->Flags & VDF_TYPE_MODELESS))
{
pParameters->result.SelectedId = Result;
EndDialog(Menu, 0);
}
else
{
ASSERT(pParameters->Flags & VDF_TYPE_MODELESS);
//Send a message containing the result to the owner of the menu
if (pParameters->Owner)
{
SendMessage(pParameters->Owner, pParameters->NotificationMsg, Result, (LPARAM)Menu);
}
else
{
PostMessage(pParameters->Owner, pParameters->NotificationMsg, Result, (LPARAM)Menu);
}
//it is the owners responsibility to destroy the window
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -