Solved

Customising TRemoteDatamodule problem

Posted on 2001-06-05
19
739 Views
Last Modified: 2012-06-27
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,
0
Comment
Question by:teerawatw
  • 10
  • 8
19 Comments
 
LVL 8

Accepted Solution

by:
TOndrej earned 300 total points
ID: 6162840
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
 

Author Comment

by:teerawatw
ID: 6166717
Hi TOndrej,
   Thank you very much. I'll try it immediately and tell the result.

teerawatw
0
 

Author Comment

by:teerawatw
ID: 6166915
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6166951
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6166977
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
 

Author Comment

by:teerawatw
ID: 6167756
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6167847
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
 

Author Comment

by:teerawatw
ID: 6170556
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
 

Author Comment

by:teerawatw
ID: 6170565
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 8

Expert Comment

by:TOndrej
ID: 6172992
> 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
 

Author Comment

by:teerawatw
ID: 6173242
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6173374
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
 

Author Comment

by:teerawatw
ID: 6179884
Hi TOndrej,

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

   Thank you again,
   teerawat
0
 

Author Comment

by:teerawatw
ID: 6185659
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6185713
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
 

Author Comment

by:teerawatw
ID: 6190022
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
 

Author Comment

by:teerawatw
ID: 6190061
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
 
LVL 8

Expert Comment

by:TOndrej
ID: 6190175
It seems that there is an error in your AS_GetProviderNames method...
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 9285803
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

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now