зеркало из https://github.com/mozilla/gecko-dev.git
112 строки
4.1 KiB
C++
112 строки
4.1 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "OSKTabTipManager.h"
|
|
|
|
#include "mozilla/Preferences.h"
|
|
#include "nsDebug.h"
|
|
#include "mozilla/widget/WinRegistry.h"
|
|
|
|
#include <shellapi.h>
|
|
#include <shlobj.h>
|
|
#include <windows.h>
|
|
|
|
namespace mozilla {
|
|
namespace widget {
|
|
|
|
/**
|
|
* Get the HWND for the on-screen keyboard, if it's up. Only
|
|
* allowed for Windows 8 and higher.
|
|
*/
|
|
static HWND GetOnScreenKeyboardWindow() {
|
|
const wchar_t kOSKClassName[] = L"IPTip_Main_Window";
|
|
HWND osk = ::FindWindowW(kOSKClassName, nullptr);
|
|
if (::IsWindow(osk) && ::IsWindowEnabled(osk) && ::IsWindowVisible(osk)) {
|
|
return osk;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
// static
|
|
void OSKTabTipManager::ShowOnScreenKeyboard() {
|
|
const char* kOskPathPrefName = "ui.osk.on_screen_keyboard_path";
|
|
|
|
if (GetOnScreenKeyboardWindow()) {
|
|
return;
|
|
}
|
|
|
|
nsAutoString cachedPath;
|
|
nsresult result = Preferences::GetString(kOskPathPrefName, cachedPath);
|
|
if (NS_FAILED(result) || cachedPath.IsEmpty()) {
|
|
wchar_t path[MAX_PATH];
|
|
// The path to TabTip.exe is defined at the following registry key.
|
|
// This is pulled out of the 64-bit registry hive directly.
|
|
constexpr auto kRegKeyName =
|
|
u"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32"_ns;
|
|
if (!WinRegistry::GetString(HKEY_LOCAL_MACHINE, kRegKeyName, u""_ns, path,
|
|
WinRegistry::kLegacyWinUtilsStringFlags)) {
|
|
return;
|
|
}
|
|
|
|
std::wstring wstrpath(path);
|
|
// The path provided by the registry will often contain
|
|
// %CommonProgramFiles%, which will need to be replaced if it is present.
|
|
size_t commonProgramFilesOffset = wstrpath.find(L"%CommonProgramFiles%");
|
|
if (commonProgramFilesOffset != std::wstring::npos) {
|
|
// The path read from the registry contains the %CommonProgramFiles%
|
|
// environment variable prefix. On 64 bit Windows the
|
|
// SHGetKnownFolderPath function returns the common program files path
|
|
// with the X86 suffix for the FOLDERID_ProgramFilesCommon value.
|
|
// To get the correct path to TabTip.exe we first read the environment
|
|
// variable CommonProgramW6432 which points to the desired common
|
|
// files path. Failing that we fallback to the SHGetKnownFolderPath API.
|
|
// We then replace the %CommonProgramFiles% value with the actual common
|
|
// files path found in the process.
|
|
std::wstring commonProgramFilesPath;
|
|
std::vector<wchar_t> commonProgramFilesPathW6432;
|
|
DWORD bufferSize =
|
|
::GetEnvironmentVariableW(L"CommonProgramW6432", nullptr, 0);
|
|
if (bufferSize) {
|
|
commonProgramFilesPathW6432.resize(bufferSize);
|
|
::GetEnvironmentVariableW(L"CommonProgramW6432",
|
|
commonProgramFilesPathW6432.data(),
|
|
bufferSize);
|
|
commonProgramFilesPath =
|
|
std::wstring(commonProgramFilesPathW6432.data());
|
|
} else {
|
|
PWSTR path = nullptr;
|
|
HRESULT hres = SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0,
|
|
nullptr, &path);
|
|
if (FAILED(hres) || !path) {
|
|
return;
|
|
}
|
|
commonProgramFilesPath = nsDependentString(path).getW();
|
|
::CoTaskMemFree(path);
|
|
}
|
|
wstrpath.replace(commonProgramFilesOffset,
|
|
wcslen(L"%CommonProgramFiles%"), commonProgramFilesPath);
|
|
}
|
|
|
|
cachedPath.Assign(wstrpath.data());
|
|
Preferences::SetString(kOskPathPrefName, cachedPath);
|
|
}
|
|
|
|
const char16_t* cachedPathPtr;
|
|
cachedPath.GetData(&cachedPathPtr);
|
|
ShellExecuteW(nullptr, L"", char16ptr_t(cachedPathPtr), nullptr, nullptr,
|
|
SW_SHOW);
|
|
}
|
|
|
|
// static
|
|
void OSKTabTipManager::DismissOnScreenKeyboard() {
|
|
HWND osk = GetOnScreenKeyboardWindow();
|
|
if (osk) {
|
|
::PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0);
|
|
}
|
|
}
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|