You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi中检测Windows开始按钮(Orb)的点击事件?

在Delphi中检测并替换Windows开始菜单的实现方案

一、核心实现思路

要替换系统默认开始菜单,核心是检测开始按钮的点击触发事件,并拦截系统菜单的显示逻辑,转而展示自定义菜单。主要有两种可靠实现路径:

1. 监控开始菜单窗口的创建/显示

Windows不同版本的开始菜单对应不同的窗口类名:

  • Win7:DV2ControlHost
  • Win10/Win11:ImmersiveStartMenuWindow
  • 开始按钮本身:Win7为Start,Win10/11为StartMenuButton(隶属于Shell_TrayWnd托盘窗口)

可以通过SetWinEventHook监听系统窗口的EVENT_OBJECT_SHOW事件,精准捕获开始菜单的弹出动作,无需高权限全局钩子。

2. 拦截开始按钮的点击消息

通过FindWindowEx定位开始按钮句柄,对其进行窗口子类化,拦截WM_LBUTTONDOWN等点击消息,直接触发自定义菜单显示,同时阻止系统菜单弹出。

二、代码实现示例

1. 基于窗口事件监控的方案

unit StartMenuReplacer;

interface

uses
  Windows, Messages, SysUtils, Classes, Forms, Menus, ExtCtrls;

type
  TMainForm = class(TForm)
    TrayIcon: TTrayIcon;
    CustomStartMenu: TPopupMenu;
    miSettings: TMenuItem;
    miExit: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure miExitClick(Sender: TObject);
  private
    FEventHook: HWINEVENTHOOK;
    procedure WinEventCallback(hHook: HWINEVENTHOOK; EventID: DWORD; hWnd: HWND;
      ObjID: LONG; ChildID: LONG; ThreadID: DWORD; EventTime: DWORD); stdcall;
  public
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
begin
  // 隐藏主窗体,仅显示托盘图标
  Hide;
  TrayIcon.Visible := True;

  // 全局监听窗口显示事件
  FEventHook := SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, 0,
    @WinEventCallback, 0, 0, WINEVENT_OUTOFCONTEXT or WINEVENT_SKIPOWNPROCESS);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  if FEventHook <> 0 then
    UnhookWinEvent(FEventHook);
end;

procedure TMainForm.WinEventCallback(hHook: HWINEVENTHOOK; EventID: DWORD; hWnd: HWND;
  ObjID: LONG; ChildID: LONG; ThreadID: DWORD; EventTime: DWORD);
var
  ClassName: array[0..255] of Char;
begin
  // 仅处理顶层窗口的显示事件
  if (ObjID = OBJID_WINDOW) and (ChildID = CHILDID_SELF) then
  begin
    GetClassName(hWnd, ClassName, SizeOf(ClassName));
    // 匹配Win10/11开始菜单窗口类名
    if StrIComp(ClassName, 'ImmersiveStartMenuWindow') = 0 then
    begin
      // 关闭系统默认开始菜单
      SendMessage(hWnd, WM_CLOSE, 0, 0);
      // 在屏幕左下角显示自定义菜单(可根据开始按钮位置调整)
      CustomStartMenu.Popup(Screen.WorkAreaLeft, Screen.WorkAreaHeight - CustomStartMenu.Height);
    end;
  end;
end;

procedure TMainForm.miExitClick(Sender: TObject);
begin
  Close;
end;

2. 基于开始按钮子类化的方案

function GetStartButtonHandle: HWND;
var
  TrayWnd: HWND;
begin
  TrayWnd := FindWindow('Shell_TrayWnd', nil);
  if TrayWnd <> 0 then
    // 适配Win10/11的开始按钮类名
    Result := FindWindowEx(TrayWnd, 0, 'StartMenuButton', nil)
  else
    Result := 0;
end;

var
  OldStartBtnProc: WNDPROC;

function StartBtnSubclassProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  // 拦截左键点击消息
  if Msg = WM_LBUTTONDOWN then
  begin
    // 显示自定义菜单
    MainForm.CustomStartMenu.Popup(Screen.WorkAreaLeft, Screen.WorkAreaHeight - MainForm.CustomStartMenu.Height);
    Result := 0; // 阻止系统处理该消息
    Exit;
  end;
  // 其他消息交给原窗口过程
  Result := CallWindowProc(OldStartBtnProc, hWnd, Msg, wParam, lParam);
end;

// 在窗体创建时调用该函数
procedure TMainForm.SubclassStartButton;
var
  StartBtn: HWND;
begin
  StartBtn := GetStartButtonHandle;
  if StartBtn <> 0 then
  begin
    OldStartBtnProc := WNDPROC(GetWindowLongPtr(StartBtn, GWLP_WNDPROC));
    SetWindowLongPtr(StartBtn, GWLP_WNDPROC, LONG_PTR(@StartBtnSubclassProc));
  end;
end;

三、附加功能实现

1. 随Windows启动

通过修改注册表启动项实现:

procedure AddToStartup;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', True) then
    begin
      Reg.WriteString('CustomStartMenu', Application.ExeName);
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

2. 系统托盘运行

直接使用Delphi的TTrayIcon组件,设置图标和右键菜单,启动时隐藏主窗体即可。

注意事项

  • 不同Windows版本的窗口类名存在差异,需做兼容性判断;
  • 窗口子类化或全局事件监听可能需要管理员权限,否则会被UAC拦截;
  • 拦截系统核心组件可能影响系统稳定性,需充分测试。

内容的提问来源于stack exchange,提问作者NettixCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:37:42