【问题标题】:Hide Taskbar button in FMX on Windows在 Windows 上的 FMX 中隐藏任务栏按钮
【发布时间】:2018-12-13 16:01:31
【问题描述】:

我希望能够从任务栏中删除我的 Win32 应用程序的按钮。我也希望以后能够将其添加回来。如何才能做到这一点?我找到了this approach,但它是用 Delphi 编写的,而我使用的是 C++。

我尝试了modifying this code,将 Remy 的一行代码更改为:

SetWindowLong(hWnd, GWL_EXSTYLE, Style | WS_EX_APPWINDOW); 

SetWindowLong(hWnd, GWL_EXSTYLE, Style | WS_EX_TOOLWINDOW);

但这不起作用,按钮仍在任务栏上。

更新:我正在使用的代码(当然来自 Remy):

void __fastcall TForm1::CreateHandle()   // this is code from Remy i added to help me trap screen lock
{
 TForm::CreateHandle();

 HWND hWnd = Fmx::Platform::Win::FormToHWND(this);
 if (SetWindowSubclass(hWnd, &SubclassWndProc, 1, reinterpret_cast<DWORD_PTR>(this)))
 {
    MonitoringWTS = WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
    if (!MonitoringWTS)
        RemoveWindowSubclass(hWnd, &SubclassWndProc, 1);
 }
 else {
    MonitoringWTS = false;
 }

 if (hWnd != NULL)   // this code added from https://stackoverflow.com/questions/28929163/how-to-show-a-secondary-form-on-taskbar-using-fmx-c
 {
 LONG Style = GetWindowLong(hWnd, GWL_EXSTYLE); // <-- don't forget this step!
 SetWindowLong(hWnd, GWL_EXSTYLE, Style | WS_EX_APPWINDOW);
 }
}

使用 C++Builder 10.2 版本 25.0.31059.3231。

【问题讨论】:

  • 我尝试将 BorderStyle 设置为这些选项,但图标仍显示在任务栏上(Windows 10)。我尝试了更正的SetWindowLong,但也没有从任务栏中删除图标。我会将我的代码发布为上面的 UPDATE 1。
  • 您使用的是哪个版本的 C++Builder?请将其包含在您的更新中。这有很大的不同,因为不同的版本处理 FMX 窗口的方式不同。

标签: firemonkey c++builder c++builder-10.2-tokyo


【解决方案1】:

如果您还保留默认的WS_EX_APPWINDOW 样式,仅添加WS_EX_TOOLWINDOW 样式是不够的。尝试改用这个:

LONG_PTR ExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, (Style & ~WS_EX_APPWINDOW) | WS_EX_TOOLWINDOW);

不过,让TForm 像工具窗口一样工作的更简单方法是将其BorderStyle 属性设置为bsToolWindowbsSizeToolWin

但是,请注意,在 XE7+ 中,您应该使用ApplicationHWND() 来获取实际位于任务栏上的HWND,因为它可能与TForm 的窗口不同。这甚至是pointed out in an answer 对您因为它是用 Delphi 而不是 C++ 编写的而忽略的问题。相关的函数调用不会改变,只是代码语法。

试试这个:

#include <FMX.Platform.Win.hpp>
#include <Winapi.Windows.hpp>

void HideAppOnTaskbar()
{
    HWND hAppWnd = Fmx::Platform::Win::ApplicationHWND();
    ShowWindow(hAppWnd, SW_HIDE);
    LONG_PTR ExStyle = GetWindowLongPtr(hAppWnd, GWL_EXSTYLE);
    SetWindowLongPtr(hAppWnd, GWL_EXSTYLE, (ExStyle & ~WS_EX_APPWINDOW) | WS_EX_TOOLWINDOW);
    //ShowWindow(hAppWnd, SW_SHOW);
}

void ShowAppOnTaskbar()
{
    HWND hAppWnd = Fmx::Platform::Win::ApplicationHWND();
    ShowWindow(hAppWnd, SW_HIDE);
    LONG_PTR ExStyle = GetWindowLongPtr(hAppWnd, GWL_EXSTYLE);
    SetWindowLongPtr(hAppWnd, GWL_EXSTYLE, (ExStyle & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW);
    ShowWindow(hAppWnd, SW_SHOW);
}

void __fastcall TForm1::CreateHandle()
{
    //...
    HideAppOnTaskbar(); // or ShowAppOnTaskbar(), as needed
}

【讨论】:

  • 完美运行,谢谢。我还尝试将 BorderStyle 更改为每个选项,但仍然会导致图标仍在任务栏上。我尝试了一个新的 FMX 应用程序并获得相同的结果(无论 BorderStyle 设置如何,始终在任务栏上显示图标)。我不知道如何处理 Delphi 代码,因为我是一条离开水的鱼。
  • 太棒了!
  • Remy - 我在 FormShow 事件中从 SQLite 数据库加载一些用户首选项。我想存储一个变量来控制任务栏按钮的“隐藏”或“显示”。看起来 CreateHandle 在 FormShow 之前触发。我在 CreateHandle 函数中尝试了我的 SQLite 代码,但我认为现在还为时过早,我得到了 fireac 错误。我猜是因为表单没有构建,并且 fireac 组件还没有准备好。我在想我可能必须将该首选项(显示或隐藏任务栏按钮)保存到文本文件中。
  • @relayman357 尝试覆盖表单的 Loaded() 方法,该方法在 DFM 完成流式传输后调用。
  • @relayman357 使用注册表比使用文件更有意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多