Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Datamodule to Form Messageing ?

Posted on 1999-08-24
7
Medium Priority
?
395 Views
Last Modified: 2010-04-04
Hi everyone,

I think I need to implement a TMessage somehow but I don't have a clue how to do it. I'm wanting to advertise that a datasource record change has occured from a datamodule, to a none-data-aware TMemo on a form that 'uses' the datamodule so that I can update the memo when the record changes. I don't want to include the form in the datamodules uses clause because that will make portability a bit of a bind.

In summary, broadcasting a message from within the datasource.OnChange with a message handler for that message on a separate form that contains the TMemo. It would be better if I could have used a TDBMemo as a calculated field, but delphi 3 standard wouldn't let me.

I *think* that's clear ??

can anybody give me any clues ? D3 help keeps going on about messages in component classes, and even then the help seems fragmented, which doesn't help me because I'm wanting to use them within the App body.

Thanks in advance

Darren
0
Comment
Question by:elkiors
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 10

Accepted Solution

by:
Lischke earned 200 total points
ID: 1396108
Apart from the fact that I wouldn't recommend broadcasting messages (this can take several seconds on specific machines) you can do that quite easily. First define your own message (this isn't critial as you are going to use this message only in your application) like:

const WM_MYBROADCAST = WM_USER + 11;

Then when you need to broadcast the message simply call:

  SendMessage(HWND_BROADCAST, WM_MYBROADCAST, 0, 0);

The last two parameters can be used to pass IDs or something other along.

In the target form you can write:

type
  TMyForm = class(TForm)
  private
    procedure WMBroadCast(var Message: TMessage); message WM_MYBROADCAST;
  end;

and:

procedure TMyForm.WMBroadCast(var Message: TMessage);

begin
  // do what ever you need here
end;

Ciao, Mike
0
 

Author Comment

by:elkiors
ID: 1396109
Mike:

If you don't recommend it, is there a better (read elegant or faster) way to do it ?

Darren
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1396110
Mmmh, what about using a simple public property or method in the target form which you can set when something changed in the data module? This is the way all DB aware components go:

type
  TMyForm = class(TForm)
  public
    procedure DBChanged;
  end;

Now in your data module you would just call MyForm.DBChanged to let the form know that it has to update its display.

You can also extend this by using a list of forms in your data module. Each form which needs update notifications can register itself in the data module. On registration a method is passed (or the form reference, this doesn't matter) and the data module adds the given form/method to its internal list. Then, on change, it iterates through this list and calls all registered forms to let them know about the change. That's what I would do...

Ciao, Mike
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:elkiors
ID: 1396111
Mike, As I mentioned earlier I don't really want to reference the forms directly in the module .. however, I might need to do this because the SendMessage ISN'T working. I implemented it directly into my project with no luck, so I tried it with just a form containing a button and a Memo, so that on button click I added a line to the memo. (Yes I know I could have implemented the memo.add within the button.onclick but it was the messaging I was testing) only when I used the Tform1.Handle in the place of HWND_BROADCAST could I get it to work. So maybe I should ask How to get the correct window handle to insert into the SendMessage.

I'm not very good at this programming lark am I !

Darren
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1396112
Hi Darran,

I should have told you (and myself think of) that broadcast messages are only sent to top level windows. In Delphi this is the application itself. You can do the following to get the broadcast message:

1) Call HookMainWindow from within the from's create method to register an own message handler.
2) In this message handler compare the incoming messages with WM_MYBROADCAST and act accordingly.
3) In the form's destroy method call UnhookMainWindow to unregister your message handler.

Regarding the other solution I gave you. I might sound a bit strange but you can do the following without needing to "uses" any of your forms in the data modul.

1) Define an own form class this way:
type
  TNotifyForm = class(TForm)
  public
    procedure NotifyChange; virtual; abstract;
  end;

2) Change your form's ancestor class in the form's source code:
type
  TMyForm = class(TNotifyForm)
  public
    procedure NotifyChange; override;
  end;

This will still work (also at design time) as there's only a new abstract method in the (else unchanged) original TForm class. You have to "uses" your data module in the interface part of your form to get this working, but you have to do this anyway, else you wouldn't be able to read the databases.

3) In your data modul write a RegisterNotification method and call it from your form passing the form itself as parameter. In this method simply add the past form (which should be of class TNotifyForm) to an internal TList object.

4) When it comes to notification then iterate through this list:

procedure TMyDataModule.DoNotification;

var I: Integer;

begin
  for I := 0 to FNotificationList.Count - 1 do
    TNotifyForm(FNotifactionList[I]).NotifyChange;
end;

5) Don't forget to unregister a form if it is destroyed.


This way you can have totally different forms without needing to reference it in the data module, as long as all forms are derived from TNotifyForm.

And don't care to change the ancestor class of your forms. It does work and does not harm your program!

Ciao, Mike
0
 
LVL 10

Expert Comment

by:Lischke
ID: 1396113
Forgot to mention that TNotifyForm should be declared in your data module.

Please read "...past form (which should..." as "...passed form (which should...".

Ciao, Mike
0
 

Author Comment

by:elkiors
ID: 1396114
Wow, I didn't expect all that! As it happens, I got round the window handle problem by just declaring an integer variable in the interface of the module defaulting to -1, then, in the on-show of the form, set the integer to the form.handle, then I used if variable>0 then sendmessage blah blah

It works, it happens fast enough to be useful for my purposes, so I'll leave it like that. Have the points though because of the extra work I've caused you, and for helping me out with the messaging.

As always, thanks to you and E-E for getting me out of a predicament.

Cheers

Darren
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question