2025-11-28 00:35:46 +09:00

353 lines
9.1 KiB
C

// 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
// spellprint.h : Implementation of helper functions to print various spell checking information
#pragma once
#include "util.h"
#include <stdio.h>
#include <objidl.h>
#include <strsafe.h>
#include <spellcheck.h>
inline HRESULT PrintAvailableLanguages(_In_ ISpellCheckerFactory* spellCheckerFactory)
{
IEnumString* enumLanguages = nullptr;
HRESULT hr = spellCheckerFactory->get_SupportedLanguages(&enumLanguages);
if (SUCCEEDED(hr))
{
wprintf(L"Available languages:\n");
}
if (SUCCEEDED(hr))
{
hr = PrintEnumString(enumLanguages, nullptr);
}
if (nullptr != enumLanguages)
{
enumLanguages->Release();
}
PrintErrorIfFailed(L"PrintAvailableLanguages", hr);
return hr;
}
inline HRESULT PrintSpellingError(_In_ ISpellChecker* spellChecker, _In_ PCWSTR text, _In_ ISpellingError* spellingError)
{
ULONG startIndex = 0;
ULONG errorLength = 0;
CORRECTIVE_ACTION correctiveAction = CORRECTIVE_ACTION_NONE;
HRESULT hr = spellingError->get_StartIndex(&startIndex);
if (SUCCEEDED(hr))
{
hr = spellingError->get_Length(&errorLength);
}
if(SUCCEEDED(hr))
{
hr = spellingError->get_CorrectiveAction(&correctiveAction);
}
if (SUCCEEDED(hr))
{
wchar_t misspelled[MAX_PATH];
hr = StringCchCopyN(misspelled, ARRAYSIZE(misspelled), text + startIndex, errorLength);
if (SUCCEEDED(hr))
{
wprintf(L"%s [%u, %u] is misspelled. ", misspelled, startIndex, startIndex + errorLength - 1);
if(CORRECTIVE_ACTION_GET_SUGGESTIONS == correctiveAction)
{
wprintf(L"Suggestions:\n");
IEnumString* enumSuggestions = nullptr;
hr = spellChecker->Suggest(misspelled, &enumSuggestions);
if (SUCCEEDED(hr))
{
hr = PrintEnumString(enumSuggestions, L"\t");
wprintf(L"\n");
enumSuggestions->Release();
}
}
else if (CORRECTIVE_ACTION_REPLACE == correctiveAction)
{
wprintf(L"It should be autocorrected to:\n");
PWSTR replacement = nullptr;
hr = spellingError->get_Replacement(&replacement);
if (SUCCEEDED(hr))
{
wprintf(L"\t%s\n\n", replacement);
CoTaskMemFree(replacement);
}
}
else if (CORRECTIVE_ACTION_DELETE == correctiveAction)
{
wprintf(L"It should be deleted.\n\n");
}
else
{
wprintf(L"Invalid corrective action.\n\n");
}
}
}
PrintErrorIfFailed(L"PrintSpellingError", hr);
return hr;
}
inline HRESULT PrintSpellingErrors(_In_ ISpellChecker* spellChecker, _In_ PCWSTR text, _Inout_ IEnumSpellingError* enumSpellingError)
{
HRESULT hr = S_OK;
size_t numErrors = 0;
while (S_OK == hr)
{
ISpellingError* spellingError = nullptr;
hr = enumSpellingError->Next(&spellingError);
if (S_OK == hr)
{
++numErrors;
hr = PrintSpellingError(spellChecker, text, spellingError);
spellingError->Release();
}
}
if (0 == numErrors)
{
wprintf(L"No errors.\n\n");
}
PrintErrorIfFailed(L"PrintSpellingErrors", hr);
return (SUCCEEDED(hr) ? S_OK : hr);
}
inline HRESULT PrintLanguage(_In_ ISpellChecker* spellChecker)
{
PWSTR languageTag = nullptr;
HRESULT hr = spellChecker->get_LanguageTag(&languageTag);
if (SUCCEEDED(hr))
{
wprintf(L"Language: %s\n\n", languageTag);
CoTaskMemFree(languageTag);
}
PrintErrorIfFailed(L"PrintLanguage", hr);
return hr;
}
inline HRESULT PrintSpellCheckerIdAndName(_In_ ISpellChecker* spellChecker)
{
PWSTR spellCheckerId = nullptr;
PWSTR localizedName = nullptr;
HRESULT hr = spellChecker->get_Id(&spellCheckerId);
if (SUCCEEDED(hr))
{
hr = spellChecker->get_LocalizedName(&localizedName);
}
if (SUCCEEDED(hr))
{
wprintf(L"Provider: %s (%s)\n\n", spellCheckerId, localizedName);
}
if (nullptr != localizedName)
{
CoTaskMemFree(localizedName);
}
if (nullptr != spellCheckerId)
{
CoTaskMemFree(spellCheckerId);
}
PrintErrorIfFailed(L"PrintSpellCheckerIdAndName", hr);
return hr;
}
inline HRESULT PrintOptionHeading(_In_ IOptionDescription* optionDescription)
{
PWSTR optionHeading = nullptr;
HRESULT hr = optionDescription->get_Heading(&optionHeading);
if (SUCCEEDED(hr))
{
if (wcslen(optionHeading) > 0)
{
wprintf(L"\t%s\n", optionHeading);
}
CoTaskMemFree(optionHeading);
}
PrintErrorIfFailed(L"PrintOptionHeading", hr);
return hr;
}
inline HRESULT PrintOptionDescription(_In_ IOptionDescription* optionDescription)
{
PWSTR description = nullptr;
HRESULT hr = optionDescription->get_Description(&description);
if (SUCCEEDED(hr))
{
if (wcslen(description) > 0)
{
wprintf(L"\t%s\n", description);
}
CoTaskMemFree(description);
}
PrintErrorIfFailed(L"PrintOptionDescription", hr);
return hr;
}
inline HRESULT PrintSingleLabel(_Inout_ IEnumString* enumString, _In_ BYTE optionValue)
{
LPOLESTR label = nullptr;
HRESULT hr = enumString->Next(1, &label, nullptr);
if (S_OK == hr)
{
PCWSTR optionState = (optionValue == 1) ? L"on" : L"off";
wprintf(L"\t%s (current %s)\n", label, optionState);
CoTaskMemFree(label);
}
PrintErrorIfFailed(L"PrintSingleLabel", hr);
return (SUCCEEDED(hr) ? S_OK : hr);
}
inline HRESULT PrintMultipleLabels(_Inout_ IEnumString* enumString, _In_ BYTE optionValue)
{
HRESULT hr = S_OK;
for (int i = 0; (S_OK == hr) ; ++i)
{
LPOLESTR label = nullptr;
hr = enumString->Next(1, &label, nullptr);
if (S_OK == hr)
{
PCWSTR currentText = (optionValue == static_cast<BYTE>(i)) ? L"(current)" : L"";
wprintf(L"\t[%d] %s %s\n", i, label, currentText);
CoTaskMemFree(label);
}
}
PrintErrorIfFailed(L"PrintMultipleLabels", hr);
return (SUCCEEDED(hr) ? S_OK : hr);
}
inline HRESULT PrintOptionLabels(_In_ ISpellChecker* spellChecker, _In_ PCWSTR optionId, _In_ IOptionDescription* optionDescription)
{
BYTE optionValue;
HRESULT hr = spellChecker->GetOptionValue(optionId, &optionValue);
if (SUCCEEDED(hr))
{
IEnumString* enumLabels = nullptr;
hr = optionDescription->get_Labels(&enumLabels);
if (SUCCEEDED(hr))
{
bool hasOneLabel;
hr = HasSingleString(enumLabels, &hasOneLabel);
if (SUCCEEDED(hr))
{
if (hasOneLabel)
{
hr = PrintSingleLabel(enumLabels, optionValue);
}
else
{
hr = PrintMultipleLabels(enumLabels, optionValue);
}
}
}
if (nullptr != enumLabels)
{
enumLabels->Release();
}
}
PrintErrorIfFailed(L"PrintOptionLabels", hr);
return hr;
}
inline HRESULT PrintOption(_In_ ISpellChecker* spellChecker, _In_ PCWSTR optionId)
{
wprintf(L"\t%s\n", optionId);
IOptionDescription* optionDescription = nullptr;
HRESULT hr = spellChecker->GetOptionDescription(optionId, &optionDescription);
if (SUCCEEDED(hr))
{
hr = PrintOptionHeading(optionDescription);
}
if (SUCCEEDED(hr))
{
hr = PrintOptionDescription(optionDescription);
}
if (SUCCEEDED(hr))
{
hr = PrintOptionLabels(spellChecker, optionId, optionDescription);
}
PrintErrorIfFailed(L"PrintOption", hr);
return hr;
}
inline HRESULT PrintSpellingOptions(_In_ ISpellChecker* spellChecker)
{
wprintf(L"Options:\n");
IEnumString* enumOptionIds = nullptr;
HRESULT hr = spellChecker->get_OptionIds(&enumOptionIds);
while (S_OK == hr)
{
LPOLESTR optionId = nullptr;
hr = enumOptionIds->Next(1, &optionId, nullptr);
if (S_OK == hr)
{
hr = PrintOption(spellChecker, optionId);
wprintf(L"\n");
CoTaskMemFree(optionId);
}
}
wprintf(L"\n");
if (nullptr != enumOptionIds)
{
enumOptionIds->Release();
}
PrintErrorIfFailed(L"PrintSpellingOptions", hr);
return hr;
}
inline HRESULT PrintInfoAndOptions(_In_ ISpellChecker* spellChecker)
{
HRESULT hr = PrintLanguage(spellChecker);
if (SUCCEEDED(hr))
{
hr = PrintSpellCheckerIdAndName(spellChecker);
}
if (SUCCEEDED(hr))
{
hr = PrintSpellingOptions(spellChecker);
}
PrintErrorIfFailed(L"PrintInfoAndOptions", hr);
return hr;
}