// Copyright (c) Microsoft Corporation.// Licensed under the MIT license.#include "precomp.h"#include "utils.hpp"#include "..\interactivity\inc\ServiceLocator.hpp"#include "srvinit.h"short CalcWindowSizeX(const SMALL_RECT& rect) noexcept{return rect.Right - rect.Left + 1;}short CalcWindowSizeY(const SMALL_RECT& rect) noexcept{return rect.Bottom - rect.Top + 1;}short CalcCursorYOffsetInPixels(const short sFontSizeY, const ULONG ulSize) noexcept{// TODO: MSFT 10229700 - Note, we want to likely enforce that this isn't negative.// Pretty sure there's not a valid case for negative offsets here.return (short)((sFontSizeY)-(ulSize));}WORD ConvertStringToDec(_In_ PCWSTR pwchToConvert, _Out_opt_ PCWSTR * const ppwchEnd) noexcept{WORD val = 0;while (*pwchToConvert != L'0円'){WCHAR ch = *pwchToConvert;if (L'0' <= ch && ch <= L'9'){val = (val * 10) + (ch - L'0');}else{break;}pwchToConvert++;}if (nullptr != ppwchEnd){*ppwchEnd = pwchToConvert;}return val;}// Routine Description:// - Retrieves string resources from our resource files.// Arguments:// - id - Resource id from resource.h to the string we need to load.// Return Value:// - The string resourcestd::wstring _LoadString(const UINT id){const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();WCHAR ItemString[70];size_t ItemLength = 0;LANGID LangId;const NTSTATUS Status = GetConsoleLangId(gci.OutputCP, &LangId);if (NT_SUCCESS(Status)){ItemLength = s_LoadStringEx(ServiceLocator::LocateGlobals().hInstance, id, ItemString, ARRAYSIZE(ItemString), LangId);}if (!NT_SUCCESS(Status) || ItemLength == 0){ItemLength = LoadStringW(ServiceLocator::LocateGlobals().hInstance, id, ItemString, ARRAYSIZE(ItemString));}return std::wstring(ItemString, ItemLength);}// Routine Description:// - Helper to retrieve string resources from a MUI with a particular LANGID.// Arguments:// - hModule - The module related to loading the resource// - wID - The resource ID number// - lpBuffer - Buffer to place string data when read.// - cchBufferMax - Size of buffer// - wLangId - Language ID of resources that we should retrieve.UINT s_LoadStringEx(_In_ HINSTANCE hModule, _In_ UINT wID, _Out_writes_(cchBufferMax) LPWSTR lpBuffer, _In_ UINT cchBufferMax, _In_ WORD wLangId){// Make sure the parms are valid.if (lpBuffer == nullptr){return 0;}UINT cch = 0;// String Tables are broken up into 16 string segments. Find the segment containing the string we are interested in.HANDLE const hResInfo = FindResourceEx(hModule, RT_STRING, (LPTSTR)((LONG_PTR)(((USHORT)wID >> 4) + 1)), wLangId);if (hResInfo != nullptr){// Load that segment.HANDLE const hStringSeg = (HRSRC)LoadResource(hModule, (HRSRC)hResInfo);// Lock the resource.LPTSTR lpsz;if (hStringSeg != nullptr && (lpsz = (LPTSTR)LockResource(hStringSeg)) != nullptr){// Move past the other strings in this segment. (16 strings in a segment -> & 0x0F)wID &= 0x0F;for (;;){cch = *((WCHAR *)lpsz++); // PASCAL like string count// first WCHAR is count of WCHARsif (wID-- == 0){break;}lpsz += cch; // Step to start if next string}// chhBufferMax == 0 means return a pointer to the read-only resource buffer.if (cchBufferMax == 0){*(LPTSTR *)lpBuffer = lpsz;}else{// Account for the nullptrcchBufferMax--;// Don't copy more than the max allowed.if (cch > cchBufferMax)cch = cchBufferMax;// Copy the string into the buffer.memmove(lpBuffer, lpsz, cch * sizeof(WCHAR));}}}// Append a nullptr.if (cchBufferMax != 0){lpBuffer[cch] = 0;}return cch;}// Routine Description:// - Compares two coordinate positions to determine whether they're the same, left, or right within the given buffer size// Arguments:// - bufferSize - The size of the buffer to use for measurements.// - coordFirst - The first coordinate position// - coordSecond - The second coordinate position// Return Value:// - Negative if First is to the left of the Second.// - 0 if First and Second are the same coordinate.// - Positive if First is to the right of the Second.// - This is so you can do s_CompareCoords(first, second) <= 0 for "first is left or the same as second".// (the < looks like a left arrow :D)// - The magnitude of the result is the distance between the two coordinates when typing characters into the buffer (left to right, top to bottom)int Utils::s_CompareCoords(const COORD bufferSize, const COORD coordFirst, const COORD coordSecond) noexcept{const short cRowWidth = bufferSize.X;// Assert that our coordinates are within the expected boundariesconst short cRowHeight = bufferSize.Y;FAIL_FAST_IF(!(coordFirst.X >= 0 && coordFirst.X < cRowWidth));FAIL_FAST_IF(!(coordSecond.X >= 0 && coordSecond.X < cRowWidth));FAIL_FAST_IF(!(coordFirst.Y >= 0 && coordFirst.Y < cRowHeight));FAIL_FAST_IF(!(coordSecond.Y >= 0 && coordSecond.Y < cRowHeight));// First set the distance vertically// If first is on row 4 and second is on row 6, first will be -2 rows behind second * an 80 character row would be -160.// For the same row, it'll be 0 rows * 80 character width = 0 difference.int retVal = (coordFirst.Y - coordSecond.Y) * cRowWidth;// Now adjust for horizontal differences// If first is in position 15 and second is in position 30, first is -15 left in relation to 30.retVal += (coordFirst.X - coordSecond.X);// Further notes:// If we already moved behind one row, this will help correct for when first is right of second.// For example, with row 4, col 79 and row 5, col 0 as first and second respectively, the distance is -1.// Assume the row width is 80.// Step one will set the retVal as -80 as first is one row behind the second.// Step two will then see that first is 79 - 0 = +79 right of second and add 79// The total is -80 + 79 = -1.return retVal;}// Routine Description:// - Compares two coordinate positions to determine whether they're the same, left, or right// Arguments:// - coordFirst - The first coordinate position// - coordSecond - The second coordinate position// Return Value:// - Negative if First is to the left of the Second.// - 0 if First and Second are the same coordinate.// - Positive if First is to the right of the Second.// - This is so you can do s_CompareCoords(first, second) <= 0 for "first is left or the same as second".// (the < looks like a left arrow :D)// - The magnitude of the result is the distance between the two coordinates when typing characters into the buffer (left to right, top to bottom)int Utils::s_CompareCoords(const COORD coordFirst, const COORD coordSecond) noexcept{const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();// find the width of one rowconst COORD coordScreenBufferSize = gci.GetActiveOutputBuffer().GetBufferSize().Dimensions();return s_CompareCoords(coordScreenBufferSize, coordFirst, coordSecond);}// Routine Description:// - Finds the opposite corner given a rectangle and one of its corners.// - For example, finds the bottom right corner given a rectangle and its top left corner.// Arguments:// - srRectangle - The rectangle to check// - coordCorner - One of the corners of the given rectangle// Return Value:// - The opposite corner of the one given.COORD Utils::s_GetOppositeCorner(const SMALL_RECT srRectangle, const COORD coordCorner) noexcept{// Assert we were given coordinates that are indeed one of the corners of the rectangle.FAIL_FAST_IF(!(coordCorner.X == srRectangle.Left || coordCorner.X == srRectangle.Right));FAIL_FAST_IF(!(coordCorner.Y == srRectangle.Top || coordCorner.Y == srRectangle.Bottom));return { (srRectangle.Left == coordCorner.X) ? srRectangle.Right : srRectangle.Left,(srRectangle.Top == coordCorner.Y) ? srRectangle.Bottom : srRectangle.Top };}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。