Customising TRemoteDatamodule problem

Hi experts,
   I am going to write my own TRemoteDatamodule. Since I want to customize many behaviors of TRemoteDatamodule, so I don't inherit it. Instead I write new class named TMultiRDM.  I copy and paste all source codes from TRemotedDatamodule and simply replace all "TRemoteDataModule" to "TMulitRDM".
   But when I test it I find that The error occurs. It is "Property Color does not exist". I have not so much experiences in delphi component.
   Can anyone point me out in this situation?
   
   Best regards and thank you very much,
teerawatwAsked:
Who is Participating?
 
TOndrejConnect With a Mentor Commented:
Most probably you need to register your new class with Delphi IDE. (I believe that "Property Color does not exist" error message indicates that Delphi is trying to use a form designer for your module.)

Put your data module in a designtime package, add dsnide50.dcp to the package's requires list, and add RegisterCustomModule to your Register procedure:

uses
  DMDesigner, // contains TDataModuleDesignerCustomModule, source not available, only dsnide50.dcp
  DsgnIntf; // contains RegisterCustomModule

procedure Register;

begin
  RegisterCustomModule(TMultiRDM, TDataModuleDesignerCustomModule);
end;

HTH
0
 
teerawatwAuthor Commented:
Hi TOndrej,
   Thank you very much. I'll try it immediately and tell the result.

teerawatw
0
 
teerawatwAuthor Commented:
Hi TOndrej,
  I got an error message. It said that "File not found: DMDesigner.DCU" I have attached dsnide50.dcp in required list. and add uses DMDesigner, DsgnIntf; in implementation section.

  Thank you very much in advanced,
  Teerawat Wuttiwat

 
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
TOndrejCommented:
It should work.
Sounds like dsnide50.dcp is not in the requires clause of your package.

(In package editor treeview, select "Requires" and click "Add" button then browse for dsnide50.dcp in your $(Delphi)\Lib directory)
0
 
TOndrejCommented:
Additional note, you may have to edit the .dfm file manually to remove form-related properties like Color, Font.xxx and so on that Delphi saved there when it treated your module as a form by mistake.
0
 
teerawatwAuthor Commented:
Hi,
  Thank you again for yr prompt answer. I'd like to clarify my situation again.

  1) I create a new design time package named "rdmMulti.bpl"

  2) I copy and paste TRemoteDatamodule (from DataBkr) to
a unit (named MultiRDM) in that package and replace all "TRemoteDatamodule" occurrences to "TMultiRDM"

  3) I add dsnide50.dcp in package editor of "rdmMulti.bpl:

  4) I add your suggested lines in "MultiRDM" unit

      uses
       DMDesigner,  DsgnIntf;

      procedure Register;
      begin
         RegisterCustomModule(TMultiRDM,   TDataModuleDesignerCustomModule);
      end;

  5) I create a new RemoteDataModule project named "MultiProvider". I replace DataBkr with MultiRDM.
I chage TMultiProvider ancestor from TRemoteDataModule to "TMultiRDM"

  6) I compile the project and a error message occur
"File not found: DMDesigner.DCU"

  Thank you again, Do you mind tell me how can you know this kind of information?

  Teerawat
 
0
 
TOndrejCommented:
That should be simple:

Remove DMDesigner, DsgnIntf from uses clause of your MultiRDM unit, also delete the Register procedure. This unit needs to be accessed by projects so you can't make it dependent on Delphi's designtime code. In your designtime package, create a new unit, e.g. MultiRDMReg.pas:

unit MultiRDMReg;

interface

uses
  Classes, SysUtils;

procedure Register;

implementation

uses
  DMDesigner, DsgnIntf,
  MultiRDM;

procedure Register;

begin
  RegisterCustomModule(TMultiRDM, TDataDesignerCustomModule);
end;

end.

Ideally, you should create two packages:
1. runtime-only package containing the new component only
2. designtime-only package containing the registration only
 (requires the runtime package)

This way you can compile your projects with runtime packages which do not contain any designtime code which a) the final user never needs b) I believe is not legal to distribute. It's OK to distribute both your runtime and designtime packages to other developers who own a copy of Delphi.

> Do you mind tell me how can you know this kind of information?
Registering custom modules is a frequently asked question on borland newsgroups.

HTH
0
 
teerawatwAuthor Commented:
Hi again,
  Actually I'd like to ask if you had had experiences in customized TRemoteDataModule. I'd like to control how providers' name occur. But at present, I can't display any provider at all.(TMultiRDM has the same source like TRemoteDataModule (Only name was changed ))

  Thank you in advanced,
   Teerawat
0
 
teerawatwAuthor Commented:
Hi,
  I am sorry, Actually I should post this message first.
I 've done what you suggest. And the datamodule form display correctly. Is this mean that the registration of my TMultiRDM is successful?
   
   Best regards,
   Teerawat
0
 
TOndrejCommented:
> the datamodule form display correctly. Is this mean that the registration of my TMultiRDM is successful?

Yes.

> I'd like to control how providers' name occur.

Can you be more specific?
0
 
teerawatwAuthor Commented:
Hi,
  I will have provider names kept in the database. When client wants to fill the providername property of TClientDataset, Delphi IDE will automatically query from the database.

  But first, I'd like to resemble the functionality of TRemoteDatamodule. And it can not even show any provider name.


   Thank you in advanced,
   Teerawat Wuttiwat
0
 
TOndrejCommented:
If I understand correctly, you don't want to "hardcode" your providers at designtime; instead, you want to create them dynamically based on data from an external dataset.

You don't need to inherit directly from TDataModule to do that... you could inherit from TRemoteDataModule (no hassle with RegisterCustomModule) and reimplement IAppServer.AS_GetProviderNames and override GetProvider.

So you have two options:

1. Keep your current design (TMultiRDM descends from TDataModule):
This may be easier since you already got this far. In AS_GetProviderNames, run your query and return an array of provider names from the database.
In GetProvider, when a provider with the given ProviderName does not yet exist, do not raise an exception as the original code does. Instead, create it on the fly.
If you want to use TDataSetProvider, you'll probably have to also create a dataset and attach it to the new provider. (Perhaps a TQuery whose SQL property can be read from the database, too - for more flexibility.)

2. Switch to standard remote data module (TMultiRDM descends from TRemoteDataModule):
Just reimplement AS_GetProviderNames and override GetProvider.

You may also want to check some of Dan Miser's MIDAS articles/examples on http://homepages.borland.com/dmiser/midas.htm

HTH
0
 
teerawatwAuthor Commented:
Hi TOndrej,

Thank you very much, I think I will try to derive my class from TRemoteDatamodule, instead.

   Thank you again,
   teerawat
0
 
teerawatwAuthor Commented:
Hi TOndrej,
   I chose the second options. At first, the IDE can display my ProviderName correctly when I reimplement AS_GetProviderName. But After I override GetProvider function, the "server execution failed" message occur. So I change GetProvider function to the previous successful code. But it doesn't work at all. The same error still occured.

   /Thank you in advanced
   Teerawat
0
 
TOndrejCommented:
TRemoteDataModule.GetProvider raises an exception if a provider with the given name is not already in the internal list. You need to suppress that exception and create it "on the fly", e.g.

function TMultiRDM.GetProvider(const ProviderName: string): TCustomProvider;
begin
  try
    Result := inherited GetProvider(ProviderName);
  except
    Result := CreateNewProvider(ProviderName);
  end;
end;

function TMultiRDM.CreateNewProvider(const ProviderName: string): TCustomProvider;
begin
  Result := TDataSetProvider.Create(Self);
  try
  // e.g. query database for SQL, create a TQuery and assign it to Result.DataSet
  except
    FreeAndNil(Result);
    raise;
  end;
end;

Additional note, you'll have to keep track of dynamically created datasets and free them in OnDestroy. Providers will be freed by ownership (your datamodule is the Owner).
HTH
0
 
teerawatwAuthor Commented:
Hi TOndrej,
   The provider name I supplied in AS_GetProvider function did not even display. When I try to click the combo box for ProviderName property in ClientDataset the 'Server execution failed'. So I think it may not be the GetProvider function that is error.

   /Thank you in advanced again,
   Teerawat
0
 
teerawatwAuthor Commented:
Hi TOndrej,
   The provider name I supplied in AS_GetProvider function did not even display. When I try to click the combo box for ProviderName property in ClientDataset the 'Server execution failed'. So I think it may not be the GetProvider function that is error.

   /Thank you in advanced again,
   Teerawat
0
 
TOndrejCommented:
It seems that there is an error in your AS_GetProviderNames method...
0
 
DragonSlayerCommented:
teerawatw,
No comment has been added lately (812 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: Award points to TOndrej http:#6167847

Please leave any comments here within 7 days.

-- Please DO NOT accept this comment as an answer ! --

Thanks,

DragonSlayer
EE Cleanup Volunteer
0
All Courses

From novice to tech pro — start learning today.