Board index » delphi » WM_SETTINGCHANGE

WM_SETTINGCHANGE

I'm trying to trap the WM_SETTINGCHANGE message, in the following:

----------------------------------------------------------------------------
-------------------
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  WProc: TFNWndProc = Nil;
  iCount: integer;

implementation

{$R *.DFM}

function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
  Longint; stdcall;
begin
// I need to know if the user changed the wallpaper or desktop colours
  if (????????????) then
   begin
    iCount := iCount + 1;
    Form1.ListBox1.Items.Add('Counter Value: ' + inttostr(iCount));
   end;

  Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
                                    Longint(@NewWndProc)));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if WProc <> Nil then
    { Restore old window procedure }
    SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
end;

end.
----------------------------------------------------------------------------
-------------------
In the online help its says:
    To send the WM_SETTINGCHANGE message to all top-level windows, use the
SendMessage function with the hwnd     parameter set to HWND_BROADCAST.

So, is my wndproc approach correct and what do I need to do, to complete
this.  I need to know when the user changes the wallpaper or desktop
colours.  I'd really appreciate any help, I can get.  Thank you.

--
Tom

 

Re:WM_SETTINGCHANGE


Tom,

If all you want to do is to trap that message there is an easier way.  You
declare a private message handler for the message (one for each message you want
to handle), and call "inherited" in its implementation before or after you do
your stuff.

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }

Quote
>>>    procedure WMSettingChange(var Message: TWMSettingChange); message

WM_SETTINGCHANGE;
  public
    { Public declarations }
  end;

implementation

procedure TForm1.WMSettingChange(var Message: TWMSettingChange);
begin
  inherited;
  //go look at the registry key HKEY_CURRENT_USER\Control
Panel\Desktop\Wallpaper
  //to check if it changed
  //You'd probably need to save that key in OnCreate to have something to
compare with
end;

As for changing the system colors, there's a message WM_SYSCOLORCHANGE that will
be sent to the form when the system colors change.

No need to subclass the form like you did.  And besides, even if you want to
subclass the form, Delphi gives you a way to do that by just overriding the
form's WndProc protected method, like this:

TForm1 = class(TForm)
  ...
private
  ...
protected
    procedure WndProc(var Message: TMessage); override;
public
  ...
end;

procedure TForm1.WndProc(var Message: TMessage);
begin
  inherited;
  if Message.Msg = WM_SETTINGCHANGE then
  begin
    //do your thing
  end;
end;

Read the topic on "Handling Messages" in the help.

HTH

Habib

Quote
tom_viper wrote:
> I'm trying to trap the WM_SETTINGCHANGE message, in the following:

> ----------------------------------------------------------------------------
> -------------------
> unit Unit1;

> interface

> uses
>   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
>   StdCtrls;

> type
>   TForm1 = class(TForm)
>     ListBox1: TListBox;
>     procedure FormCreate(Sender: TObject);
>     procedure FormClose(Sender: TObject; var Action: TCloseAction);
>   private
>     { Private declarations }
>   public
>     { Public declarations }
>   end;

> var
>   Form1: TForm1;
>   WProc: TFNWndProc = Nil;
>   iCount: integer;

> implementation

> {$R *.DFM}

> function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint):
>   Longint; stdcall;
> begin
> // I need to know if the user changed the wallpaper or desktop colours
>   if (????????????) then
>    begin
>     iCount := iCount + 1;
>     Form1.ListBox1.Items.Add('Counter Value: ' + inttostr(iCount));
>    end;

>   Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
> end;

> procedure TForm1.FormCreate(Sender: TObject);
> begin
>   WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
>                                     Longint(@NewWndProc)));
> end;

> procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
> begin
>   if WProc <> Nil then
>     { Restore old window procedure }
>     SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
> end;

> end.

> ----------------------------------------------------------------------------
> -------------------
> In the online help its says:
>     To send the WM_SETTINGCHANGE message to all top-level windows, use the
> SendMessage function with the hwnd     parameter set to HWND_BROADCAST.

> So, is my wndproc approach correct and what do I need to do, to complete
> this.  I need to know when the user changes the wallpaper or desktop
> colours.  I'd really appreciate any help, I can get.  Thank you.

> --
> Tom

Re:WM_SETTINGCHANGE


Ya, I know how to trap the message the other two suggested ways.  But, I
thought you had to do it the way I was doing if your traping broadcast
messages.  No need to?

Alright, I thank you for responding.  I will go and add to read the registry
and hopefully perfection achieved.  Thanks again, for you feedback.

--
Tom

Quote
"H. Debs" <hd...@csi.com> wrote in message news:3A876CD1.432523B3@csi.com...
> Tom,

> If all you want to do is to trap that message there is an easier way.  You
> declare a private message handler for the message (one for each message
you want
> to handle), and call "inherited" in its implementation before or after you
do
> your stuff.

> type
>   TForm1 = class(TForm)
>     ListBox1: TListBox;
>     procedure FormCreate(Sender: TObject);
>     procedure FormClose(Sender: TObject; var Action: TCloseAction);
>   private
>     { Private declarations }
> >>>    procedure WMSettingChange(var Message: TWMSettingChange); message
> WM_SETTINGCHANGE;
>   public
>     { Public declarations }
>   end;

> implementation

> procedure TForm1.WMSettingChange(var Message: TWMSettingChange);
> begin
>   inherited;
>   //go look at the registry key HKEY_CURRENT_USER\Control
> Panel\Desktop\Wallpaper
>   //to check if it changed
>   //You'd probably need to save that key in OnCreate to have something to
> compare with
> end;

> As for changing the system colors, there's a message WM_SYSCOLORCHANGE
that will
> be sent to the form when the system colors change.

> No need to subclass the form like you did.  And besides, even if you want
to
> subclass the form, Delphi gives you a way to do that by just overriding
the
> form's WndProc protected method, like this:

> TForm1 = class(TForm)
>   ...
> private
>   ...
> protected
>     procedure WndProc(var Message: TMessage); override;
> public
>   ...
> end;

> procedure TForm1.WndProc(var Message: TMessage);
> begin
>   inherited;
>   if Message.Msg = WM_SETTINGCHANGE then
>   begin
>     //do your thing
>   end;
> end;

> Read the topic on "Handling Messages" in the help.

> HTH

> Habib

> tom_viper wrote:

> > I'm trying to trap the WM_SETTINGCHANGE message, in the following:

> --------------------------------------------------------------------------
--
> > -------------------
> > unit Unit1;

> > interface

> > uses
> >   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
> >   StdCtrls;

> > type
> >   TForm1 = class(TForm)
> >     ListBox1: TListBox;
> >     procedure FormCreate(Sender: TObject);
> >     procedure FormClose(Sender: TObject; var Action: TCloseAction);
> >   private
> >     { Private declarations }
> >   public
> >     { Public declarations }
> >   end;

> > var
> >   Form1: TForm1;
> >   WProc: TFNWndProc = Nil;
> >   iCount: integer;

> > implementation

> > {$R *.DFM}

> > function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam:
Longint):
> >   Longint; stdcall;
> > begin
> > // I need to know if the user changed the wallpaper or desktop colours
> >   if (????????????) then
> >    begin
> >     iCount := iCount + 1;
> >     Form1.ListBox1.Items.Add('Counter Value: ' + inttostr(iCount));
> >    end;

> >   Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
> > end;

> > procedure TForm1.FormCreate(Sender: TObject);
> > begin
> >   WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC,
> >                                     Longint(@NewWndProc)));
> > end;

> > procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
> > begin
> >   if WProc <> Nil then
> >     { Restore old window procedure }
> >     SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
> > end;

> > end.

> --------------------------------------------------------------------------
--
> > -------------------
> > In the online help its says:
> >     To send the WM_SETTINGCHANGE message to all top-level windows, use
the
> > SendMessage function with the hwnd     parameter set to HWND_BROADCAST.

> > So, is my wndproc approach correct and what do I need to do, to complete
> > this.  I need to know when the user changes the wallpaper or desktop
> > colours.  I'd really appreciate any help, I can get.  Thank you.

> > --
> > Tom

Re:WM_SETTINGCHANGE


Please watch your over quoting.  Thank you.

Quote
tom_viper wrote:

--
Jeff Overcash (TeamB)
      (Please do not email me directly unless  asked. Thank You)
The correct way to punctuate a sentence that starts: "Of course it is
none of my business but ~" is to place a period after the word "but".
Don't use excessive force in supplying such a moron with a period.
Cutting his throat is only a momentary pleasure and is bound to get
you talked about.   (RAH)

Re:WM_SETTINGCHANGE


Quote
tom_viper wrote:
> But, I thought you had to do it the way I was doing if your traping broadcast
> messages.  No need to?

No.

I also got your email.  It seems that the Display Properties dialog does not set
the SPIF_SENDCHANGE flag when it calls SystemParametersInfo to change the
wallpaper, so the WM_SETTINGCHANGED message is not broadcast.  So you can't
detect a change of wallpaper this way.

You could use a timer and check the registry (or Win.ini file) every now and
then.  Sorry, but that's all I can think of.  Perhaps someone else has another
idea to catch changes in wallpaper.

Habib

Re:WM_SETTINGCHANGE


That's weird, they don't do a

SystemParametersInfoSPI_SETDESKWALLPAPER,0,NIL,SPIF_SENDWININICHANGE);

But, they're probably just telling the desktop to refresh itself (the F5
thingy) or something.

Alright, maybe I'll use the timer approach.  I appreciate all your feedback.
Thank you, very much.

--
Tom

Quote
"H. Debs" <hd...@csi.com> wrote in message news:3A893B0E.CEE5E202@csi.com...
> tom_viper wrote:

> > But, I thought you had to do it the way I was doing if your traping
broadcast
> > messages.  No need to?

> No.

> I also got your email.  It seems that the Display Properties dialog does
not set
> the SPIF_SENDCHANGE flag when it calls SystemParametersInfo to change the
> wallpaper, so the WM_SETTINGCHANGED message is not broadcast.  So you
can't
> detect a change of wallpaper this way.

> You could use a timer and check the registry (or Win.ini file) every now
and
> then.  Sorry, but that's all I can think of.  Perhaps someone else has
another
> idea to catch changes in wallpaper.

> Habib

Other Threads