我需要知道我的应用程序何时收到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()
也不会。
一旦代码路径到达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
系统。
我如何回应Windows广播WM_SETTINGCHANGE
?
答案 0 :(得分:9)
Edit2:对于旧版本,通常的消息拦截应该有效......
[...]
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;
您可以使用此代码进行测试。尝试并更改TaskBar的高度或停靠侧......
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;
答案 1 :(得分:2)
在我的问题中,答案是HookMainWindow
:
procedure TdmGlobal.DataModuleCreate(Sender: TObject);
begin
...
Application.HookMainWindow(SettingChangeHook);
end;
procedure TdmGlobal.DataModuleDestroy(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;
答案 2 :(得分:2)
您可以像处理任何其他消息一样处理它。如果为它设置了一个消息处理程序,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;