Skip to content

Commit

Permalink
修复任务栏右键菜单不生效的问题
Browse files Browse the repository at this point in the history
修复笔记本电脑进入电池模式时被迫停止的问题
优化动画效果
  • Loading branch information
ALTaleX531 committed Aug 6, 2023
1 parent d5e725b commit 1e81f4d
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 66 deletions.
2 changes: 1 addition & 1 deletion TFMain/MenuAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ namespace TranslucentFlyouts::MenuAnimation
0,
1,
1,
nullptr,
Utils::GetCurrentMenuOwner(),
nullptr,
nullptr,
nullptr
Expand Down
4 changes: 2 additions & 2 deletions TFMain/MenuAnimation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ namespace TranslucentFlyouts
// Defined in win32kfull.sys!zzzMNFadeSelection
constexpr milliseconds standardFadeoutDuration{350ms};
// Defined in https://learn.microsoft.com/en-us/windows/apps/design/signature-experiences/motion
constexpr milliseconds standardPopupInDuration{333ms};
constexpr milliseconds standardPopupInDuration{250ms};
constexpr milliseconds standardFadeInDuration{87ms};
// Defined in WinUI
constexpr float standardStartPosRatio{0.666f};
constexpr float standardStartPosRatio{0.5f};
}

HRESULT CreateFadeOut(
Expand Down
11 changes: 11 additions & 0 deletions TFMain/TFMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ void CALLBACK MainDLL::HandleWinEvent(
return;
}

if (
Utils::IsValidFlyout(hWnd) &&
MainDLL::IsHookGlobalInstalled() &&
//ThemeHelper::IsThemeAvailable() &&
//!ThemeHelper::IsHighContrast() &&
!GetSystemMetrics(SM_CLEANBOOT)
)
{
mainDLL.Startup();
}

auto& callbackList{GetInstance().m_callbackList};

if (!callbackList.empty())
Expand Down
29 changes: 28 additions & 1 deletion TFMain/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ namespace TranslucentFlyouts
return rf.fake_ptr;
}

static inline auto MakeHRErrStr(HRESULT hr)
{
WCHAR szError[MAX_PATH + 1]{};
FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
hr,
0,
szError,
_countof(szError),
nullptr
);

return std::wstring{szError};
}

static inline std::wstring make_current_folder_file_str(std::wstring_view baseFileName)
{
WCHAR filePath[MAX_PATH + 1]{L""};
Expand All @@ -42,15 +58,18 @@ namespace TranslucentFlyouts
return std::wstring{filePath};
}

static inline std::optional<wil::unique_rouninitialize_call> RoInit()
static inline std::optional<wil::unique_rouninitialize_call> RoInit(HRESULT* hresult = nullptr)
{
HRESULT hr{::RoInitialize(RO_INIT_SINGLETHREADED)};

if (SUCCEEDED(hr) || hr == S_FALSE)
{
if (hresult) { *hresult = S_OK; }
return wil::unique_rouninitialize_call{};
}

if (hresult) { *hresult = hr; }

return std::nullopt;
}

Expand Down Expand Up @@ -117,6 +136,14 @@ namespace TranslucentFlyouts
return false;
}

static bool IsValidFlyout(HWND hWnd)
{
return
IsWin32PopupMenu(hWnd) ||
IsWindowClass(hWnd, L"DropDown") ||
IsWindowClass(hWnd, L"Listviewpopup");
}

static inline HWND GetCurrentMenuOwner()
{
GUITHREADINFO guiThreadInfo{sizeof(GUITHREADINFO)};
Expand Down
248 changes: 186 additions & 62 deletions TFMain/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,6 @@ BOOL APIENTRY DllMain(
{
bResult = FALSE;
}
else
{
if (
MainDLL::IsHookGlobalInstalled() &&
//ThemeHelper::IsThemeAvailable() &&
//!ThemeHelper::IsHighContrast() &&
!GetSystemMetrics(SM_CLEANBOOT)
)
{
MainDLL::GetInstance().Startup();
}
}
break;
}

Expand All @@ -48,6 +36,146 @@ BOOL APIENTRY DllMain(
return bResult;
}

HRESULT WINAPI Install() try
{
using namespace wil;
using namespace TranslucentFlyouts;

HRESULT hr{S_OK};
auto CleanUp{Utils::RoInit(&hr)};
THROW_IF_FAILED(hr);

{
com_ptr<ITaskService> taskService{wil::CoCreateInstance<ITaskService>(CLSID_TaskScheduler)};
THROW_IF_FAILED(taskService->Connect(_variant_t{}, _variant_t{}, _variant_t{}, _variant_t{}));

com_ptr<ITaskFolder> rootFolder{nullptr};
THROW_IF_FAILED(taskService->GetFolder(_bstr_t("\\"), &rootFolder));

com_ptr<ITaskDefinition> taskDefinition{nullptr};
THROW_IF_FAILED(taskService->NewTask(0, &taskDefinition));

com_ptr<IRegistrationInfo> regInfo{nullptr};
THROW_IF_FAILED(taskDefinition->get_RegistrationInfo(&regInfo));
THROW_IF_FAILED(regInfo->put_Author(const_cast<BSTR>(L"ALTaleX")));
THROW_IF_FAILED(regInfo->put_Description(const_cast<BSTR>(L"This task ensures most of the flyout translucent all the time.")));

{
com_ptr<IPrincipal> principal{nullptr};
THROW_IF_FAILED(taskDefinition->get_Principal(&principal));

THROW_IF_FAILED(principal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN));
THROW_IF_FAILED(principal->put_RunLevel(TASK_RUNLEVEL_HIGHEST));
}

{
com_ptr<ITaskSettings> setting{nullptr};
THROW_IF_FAILED(taskDefinition->get_Settings(&setting));

THROW_IF_FAILED(setting->put_StopIfGoingOnBatteries(VARIANT_FALSE));
THROW_IF_FAILED(setting->put_DisallowStartIfOnBatteries(VARIANT_FALSE));
THROW_IF_FAILED(setting->put_AllowDemandStart(VARIANT_TRUE));
THROW_IF_FAILED(setting->put_StartWhenAvailable(VARIANT_FALSE));
THROW_IF_FAILED(setting->put_MultipleInstances(TASK_INSTANCES_PARALLEL));
}

{
com_ptr<IExecAction> execAction{nullptr};
{
com_ptr<IAction> action{nullptr};
{
com_ptr<IActionCollection> actionColl{nullptr};
THROW_IF_FAILED(taskDefinition->get_Actions(&actionColl));
THROW_IF_FAILED(actionColl->Create(TASK_ACTION_EXEC, &action));
}
action.query_to(&execAction);
}

WCHAR modulePath[MAX_PATH + 1] {};
RETURN_LAST_ERROR_IF(!GetModuleFileName(HINST_THISCOMPONENT, modulePath, MAX_PATH));

THROW_IF_FAILED(
execAction->put_Path(
const_cast<BSTR>(L"Rundll32")
)
);
THROW_IF_FAILED(
execAction->put_Arguments(
const_cast<BSTR>(
std::format(L"\"{}\",Main", modulePath).c_str()
)
)
);
}

com_ptr<ITriggerCollection> triggerColl{nullptr};
THROW_IF_FAILED(taskDefinition->get_Triggers(&triggerColl));

com_ptr<ITrigger> trigger{nullptr};
THROW_IF_FAILED(triggerColl->Create(TASK_TRIGGER_LOGON, &trigger));

com_ptr<IRegisteredTask> registeredTask{nullptr};
BSTR name
{
#ifdef _WIN64
const_cast<BSTR>(L"TranslucentFlyouts Autorun Task")
#else
const_cast<BSTR>(L"TranslucentFlyouts Autorun Task (x86)")
#endif
};
THROW_IF_FAILED(
rootFolder->RegisterTaskDefinition(
name,
taskDefinition.get(),
TASK_CREATE_OR_UPDATE,
_variant_t{},
_variant_t{},
TASK_LOGON_INTERACTIVE_TOKEN,
_variant_t{},
& registeredTask
)
);
}

return S_OK;
}
CATCH_LOG_RETURN_HR(wil::ResultFromCaughtException())

HRESULT WINAPI Uninstall() try
{
using namespace wil;
using namespace TranslucentFlyouts;

HRESULT hr{S_OK};
auto CleanUp{Utils::RoInit(&hr)};
THROW_IF_FAILED(hr);

{
com_ptr<ITaskService> taskService{wil::CoCreateInstance<ITaskService>(CLSID_TaskScheduler)};
THROW_IF_FAILED(taskService->Connect(_variant_t{}, _variant_t{}, _variant_t{}, _variant_t{}));

com_ptr<ITaskFolder> rootFolder{nullptr};
THROW_IF_FAILED(taskService->GetFolder(_bstr_t("\\"), &rootFolder));

BSTR name
{
#ifdef _WIN64
const_cast<BSTR>(L"TranslucentFlyouts Autorun Task")
#else
const_cast<BSTR>(L"TranslucentFlyouts Autorun Task (x86)")
#endif
};
THROW_IF_FAILED(
rootFolder->DeleteTask(
name, 0
)
);
}

return S_OK;
}
CATCH_LOG_RETURN_HR(wil::ResultFromCaughtException())

int WINAPI Main(
HWND hWnd,
HINSTANCE hInstance,
Expand All @@ -63,74 +191,70 @@ int WINAPI Main(
SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
}

if (!_stricmp(lpCmdLine, "/install"))
SHELLEXECUTEINFOA sei
{
WCHAR modulePath[MAX_PATH + 1] {};
RETURN_LAST_ERROR_IF(!GetModuleFileName(HINST_THISCOMPONENT, modulePath, MAX_PATH));
sizeof(SHELLEXECUTEINFO), SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC,
nullptr,
"runas",
"rundll32",
lpCmdLine,
nullptr,
SW_HIDE
};

auto parameters
{
#ifdef _WIN64
std::format(
L"/create /sc ONLOGON /tn \"TranslucentFlyouts Autorun Task\" /rl HIGHEST /tr \"Rundll32 \\\"{}\\\",Main\"",
modulePath
)
#else
std::format(
L"/create /sc ONLOGON /tn \"TranslucentFlyouts Autorun Task (x86)\" /rl HIGHEST /tr \"Rundll32 \\\"{}\\\",Main\"",
modulePath
)
#endif
};
SHELLEXECUTEINFOW sei
HRESULT hr{S_OK};
if (!_stricmp(lpCmdLine, "/install"))
{
hr = Install();
if (SUCCEEDED(hr))
{
sizeof(SHELLEXECUTEINFO), SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC,
nullptr,
L"runas",
L"schtasks",
parameters.c_str(),
nullptr,
SW_HIDE
};

if (!ShellExecuteExW(&sei))
RestartDialog(nullptr, nullptr, EWX_LOGOFF);
}
else
{
RETURN_LAST_ERROR();
ShellMessageBoxW(
hInstance,
nullptr,
Utils::MakeHRErrStr(hr).c_str(),
nullptr,
MB_ICONERROR
);
}

RestartDialog(nullptr, nullptr, EWX_LOGOFF);
return 0;
return hr;
}

if (!_stricmp(lpCmdLine, "/uninstall"))
{
SHELLEXECUTEINFOW sei
hr = Uninstall();
if (SUCCEEDED(hr))
{
sizeof(SHELLEXECUTEINFO), SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC,
nullptr,
L"runas",
L"schtasks",
#ifdef _WIN64
L"/delete /f /tn \"TranslucentFlyouts Autorun Task\"",
#else
L"/delete /f /tn \"TranslucentFlyouts Autorun Task (x86)\"",
#endif
nullptr,
SW_HIDE
};

if (!ShellExecuteExW(&sei))
RestartDialog(nullptr, nullptr, EWX_LOGOFF);
}
else
{
RETURN_LAST_ERROR();
ShellMessageBoxW(
hInstance,
nullptr,
Utils::MakeHRErrStr(hr).c_str(),
nullptr,
MB_ICONERROR
);
}

RestartDialog(nullptr, nullptr, EWX_LOGOFF);
return 0;
return hr;
}

HRESULT hr{MainDLL::InstallHook()};
hr = MainDLL::InstallHook();
if (FAILED(hr))
{
ShellMessageBoxW(
hInstance,
nullptr,
Utils::MakeHRErrStr(hr).c_str(),
nullptr,
MB_ICONERROR
);
return hr;
}

Expand Down
Loading

0 comments on commit 1e81f4d

Please sign in to comment.