如何检测是否点击了Windows开始(Orb)按钮?

huangapple go评论73阅读模式
英文:

How to detect if Windows Start (Orb) button is clicked?

问题

在Delphi中,是否可以检测用户点击Windows的“开始”按钮(位于左下角的按钮,弹出菜单)?

我尝试创建自己的“开始”菜单,所以当用户点击“开始”按钮时,它会显示我的菜单而不是Windows的菜单。

我的概念是我的应用程序会在Windows启动时自动运行在系统托盘中,并在用户点击“开始”按钮时检测,然后显示我的菜单。

我看到一个类似的问题,但是是关于C#的:如何检测Windows“开始”菜单/开始屏幕何时打开?,但在Delphi中如何实现呢?

英文:

In Delphi, is it possible to detect when the user clicks on Windows' Start button (the button on the bottom left that brings up the menu)?

I try to create my own Start menu, so when the Start button is clicked, it will show my menu rather then Windows' menu.

My concept is my app will run automatically in the systray when Windows starts, and detect when the user clicks on the Start button then shown my menu.

I see a similar question, but in C#: How to detect when the Windows start menu / start screen opens?, but how to do that in Delphi?

答案1

得分: 0

找到解决方案使用鼠标挂钩...
首先获取“开始”按钮的大小和位置:

_handle := FindWindow('Shell_TrayWnd', nil);
_Start.Handle := FindWindowEx(_handle, 0, 'Start', nil);
GetWindowRect(_Start.Handle, _Start.Rect);

然后使用鼠标挂钩检查鼠标指针是否点击了开始按钮:

if (ms.X >= Start.Rect.Left)
and (ms.X <= Start.Rect.Right)
and (ms.Y >= Start.Rect.Top)
and (ms.Y <= Start.Rect.Bottom) then dowhatiwant ......

无论任务栏位置在左下、右下还是顶部,它都会始终找到开始按钮的位置...

更新:
我从GitHub上找到了另一个解决方案... 感谢Remy提供的线索答案以及vhanla提供的功能强大的任务栏组件,该组件具有实施Remy答案的代码。如果有人需要,我在这里分享它...

type
  // *********************************************************************//
  // Interface: IAppVisibilityEvents
  // Flags:     (0)
  // GUID:      {6584CE6B-7D82-49C2-89C9-C6BC02BA8C38}
  // *********************************************************************//
  IAppVisibilityEvents = interface(IUnknown)
    ['{6584CE6B-7D82-49C2-89C9-C6BC02BA8C38}']
    function AppVisibilityOnMonitorChanged(hMonitor: HMONITOR;
      previousMode: MONITOR_APP_VISIBILITY;
      currentMode: MONITOR_APP_VISIBILITY): HRESULT; stdcall;
    function LauncherVisibilityChange(currentVisibleState: BOOL): HRESULT; stdcall;
  end;
  
  // *********************************************************************//
  // Interface: IAppVisibility
  // Flags:     (0)
  // GUID:      {2246EA2D-CAEA-4444-A3C4-6DE827E44313}
  // *********************************************************************//
  IAppVisibility = interface(IUnknown)
    ['{2246EA2D-CAEA-4444-A3C4-6DE827E44313}']
    function GetAppVisibilityOnMonitor(monitor: HMONITOR; out pMode: MONITOR_APP_VISIBILITY): HRESULT; stdcall;
    function IsLauncherVisible(out pfVisible: BOOL): HRESULT; stdcall;
    function Advise(pCallBack: IAppVisibilityEvents; out pdwCookie: DWORD): HRESULT; stdcall;
    function Unadvise(dwCookie: DWORD): HRESULT; stdcall;
  end;

function IsStartMenuVisible: Boolean;
var
  acc: IAppVisibility;
  res: HRESULT;
  isLauncherVisible: BOOL;
begin
  Result := False;
  // 初始化COM是使用AppVisibility(CLSID_AppVisibility)对象的要求
  res := CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
  if Succeeded(res) then
  begin
    // 创建App Visibility组件
    res := CoCreateInstance(CLSID_AppVisibility, nil, CLSCTX_ALL, IID_AppVisibility, acc);
    if Succeeded(res) then
    begin
      res := acc.IsLauncherVisible(isLauncherVisible);
      if Succeeded(res) then
        Result := Boolean(isLauncherVisible);
    end;
  end;
  CoUninitialize;
end;

并调用该函数来检测开始菜单是否已打开。
英文:

found solution use mousehook ..
1st get the start button size and position

_handle := FindWindow(&#39;Shell_TrayWnd&#39;, nil);
_Start.Handle := FindWindowEx(_handle, 0, &#39;Start&#39;, nil);
GetWindowRect(_Start.Handle, _Start.Rect);

then use mousehook to check mouse pointer clicked on start button or not :

if (ms.X &gt;= Start.Rect.Left)
and (ms.X &lt;= Start.Rect.Right)
and (ms.Y &gt;= Start.Rect.Top)
and (ms.Y &lt;= Start.Rect.Bottom) then dowhatiwant ......

no matter where is TASKBAR POSITION in left bottom right or top it will always found the start button position ..

UPDATE :
i found another solutions from github .. thanks to Remy for the clue answer and vhanla for the powerfull taskbar component which has a code to implement remy answer,, i share it here if someone need it .. :

type
// *********************************************************************//
// Interface: IAppVisibilityEvents
// Flags:     (0)
// GUID:      {6584CE6B-7D82-49C2-89C9-C6BC02BA8C38}
// *********************************************************************//
  IAppVisibilityEvents = interface(IUnknown)
    [&#39;{6584CE6B-7D82-49C2-89C9-C6BC02BA8C38}&#39;]
    function AppVisibilityOnMonitorChanged(hMonitor: HMONITOR;
              previousMode: MONITOR_APP_VISIBILITY;
              currentMode: MONITOR_APP_VISIBILITY):HRESULT; stdcall;
    function LauncherVisibilityChange(currentVisibleState: BOOL): HRESULT; stdcall;
  end;
// *********************************************************************//
// Interface: IAppVisibility
// Flags:     (0)
// GUID:      {2246EA2D-CAEA-4444-A3C4-6DE827E44313}
// *********************************************************************//
  IAppVisibility = interface(IUnknown)
    [&#39;{2246EA2D-CAEA-4444-A3C4-6DE827E44313}&#39;]
    function GetAppVisibilityOnMonitor(monitor: HMONITOR; out pMode: MONITOR_APP_VISIBILITY): HRESULT; stdcall;
    function IsLauncherVisible(out pfVisible: BOOL): HRESULT; stdcall;
    function Advise(pCallBack: IAppVisibilityEvents; out pdwCookie: DWORD): HRESULT; stdcall;
    function Unadvise(dwCookie: DWORD): HRESULT; stdcall;
  end;



function IsStartMenuVisible: Boolean;
var
  acc: IAppVisibility;
  res: HRESULT;
  isLauncherVisible: BOOL;
begin
  Result := False;
  // Initialization of COM is required to use the AppVisibility (CLSID_AppVisibility) object
  res := CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
  if Succeeded(res) then
  begin
    // Create the App Visibility component
    res := CoCreateInstance(CLSID_AppVisibility, nil, CLSCTX_ALL, IID_AppVisibility, acc);
    if Succeeded(res) then
    begin
      res := acc.IsLauncherVisible(isLauncherVisible);
      if Succeeded(res) then
        Result := Boolean(isLauncherVisible);
    end;

  end;
  CoUninitialize;
end;

and call the function to detect start menu is opened or not .

huangapple
  • 本文由 发表于 2023年5月25日 00:25:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76325621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定