delphi:如何响应WM_SettingChange / WM_WinIniChange?

我需要知道什么时候我的应用程序WM_WININICHANGE WM_SETTINGCHANGE消息(以前称为WM_WININICHANGE )。

问题在于TApplication中的消息泵会在黑洞(默认处理程序)中将其发送出去 ,然后我才有机会看到它:

 procedure TApplication.WndProc(var Message: TMessage); ... begin Message.Result := 0; for I := 0 to FWindowHooks.Count - 1 do if TWindowHook(FWindowHooks[I]^)(Message) then Exit; CheckIniChange(Message); with Message do case Msg of WM_SETTINGCHANGE: begin Mouse.SettingChanged(wParam); Default; <----------------------*poof* down the sink hole end; ... end; ... end; 

过程CheckIniChange()不会抛出任何我可以处理的事件, Mouse.SettingChanged()也不会。

一旦代码path达到Default ,它将被发送到DefWindowProc排水孔,永远不会再被看到(因为WndProc所做的第一件事是将Message.Result设置为零。

我希望分配一个处理程序TApplicationEvents.OnMessage事件:

 procedure TdmGlobal.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); begin case Msg.message of WM_SETTINGCHANGE: begin // Code end; end; end; 

但是,OnMessage事件仅针对通过消息泵传来的消息而被抛出。 由于WM_SETTINGCHANGE消息是“处理”,它从来没有看到

 PeekMessage TranslateMessage DispatchMessage 

系统。

我怎样才能响应WM_SETTINGCHANGEWindows广播?

Solutions Collecting From Web of "delphi:如何响应WM_SettingChange / WM_WinIniChange?"

编辑2:对于旧版本,通常的消息拦截应该工作…

 [...] private procedure WMSettingChange(var Message: TWMSettingChange); message WM_SETTINGCHANGE; [...] procedure TForm1.WMSettingChange(var Message: TWMSettingChange); begin showMessage('SettingChange message intercept'); end; 

编辑:哎呀! 没有看到它是D5。 以下是在D2007 +。

在您的应用程序中使用OnSettingChange:

 procedure TApplication.SettingChange(var Message: TWMSettingChange); begin if Assigned(FOnSettingChange) then with Message do FOnSettingChange(Self, Flag, Section, Result); end; 

你可以测试这个代码。 尝试并更改任务栏的高度或停靠侧…

 procedure TForm1.FormCreate(Sender: TObject); begin Application.OnSettingChange := MySettingChange; end; procedure TForm1.MySettingChange(Sender: TObject; Flag: Integer; const Section: string; var Result: Integer); begin showMessage('setting changed'); end; 

答案是在我的问题,危险,无证,使用HookMainWindow

 procedure TdmGlobal.DatamoduleeCreate(Sender: TObject); begin ... Application.HookMainWindow(SettingChangeHook); end; procedure TdmGlobal.DatamoduleeDestroy(Sender: TObject); begin Application.UnhookMainWindow(SettingChangeHook); end; function TdmGlobal.SettingChangeHook(var Message: TMessage): Boolean; begin case Message.Msg of WM_SETTINGCHANGE: begin //Handler code end; end; Result := False; //continue processing end; 

你就像处理其他任何信息一样处理它。 如果您为其设置消息处理程序,则TApplication的默认处理程序将正确地路由它:

 // interface type TYourMainForm = class(TForm) // other stuff private procedure WMSettingChange(var Msg: TWMSettingChange); message WM_SETTINGCHANGE; end; // implementation procedure TYourMainForm.WMSettingChange(var Msg: TWMSettingChange); message WM_SETTINGCHANGE; begin // Whatever handling here. TWMSettingChange is defined in Messages.pas end;