📄 189.htm
字号:
procedure RecordChanged(Field: TField) <br>
-------------------------------------- <br>
This procedure gets called when: <br>
<br>
o The current record is edited <br>
o The record's text has changed <br>
<br>
If the Field parameter is non-nil then the change occured to the specified field <br>
. <br>
<br>
procedure UpdateData <br>
-------------------- <br>
This procedure is called immediately before a record is updated in the database. <br>
You can call the Abort procedure to prevent the record from being updated. <br>
<br>
4.2. How can I tell the number of the record I am on in a data set? <br>
<br>
At first glance the RecNo property for a data set appears to be what you want bu <br>
to be what you want bu <br>
t unfortunately this only works with dBase and Paradox tables. <br>
<br>
The way you can keep track of the current record number is to create a class tha <br>
t derives from TDataLink. The main things you need to do are: <br>
<br>
o Override the DataSetScrolled method to keep track of the number of times the c <br>
urrent record has been moved forwards or backwards. <br>
o Override the DataSetChanged method to determine when a jump the start or end o <br>
f the dataset has occured. <br>
<br>
You can attach an object or your class to a data source and use it to keep track <br>
of the current record. <br>
<br>
------------------------------------------------------------------------ <br>
Section 5 - VCL <br>
5.1. How can I step through the VCL source while debugging? <br>
<br>
Copy the VCL source modules you are interested in stepping through to your proje <br>
ct directory then rebuild the VCL library. You will then be able to step throug <br>
h the VCL source modules. <br>
<br>
5.2. My component references other components. How can I tell if a component my <br>
other components. How can I tell if a component my <br>
component references has been deleted? <br>
<br>
From Max Nilson <br>
<br>
A little documented part of TComponent and its decendants is the the <br>
Notification method. This method is primarily used to detect cases where <br>
components that you are referencing are being deleted. It does have other <br>
features but I have not yet thought of a reason to use them. For Borlands <br>
explanation of these things search for Notification and FreeNotification in <br>
the VCL help. Don't bother looking in the Component Writer's Guide 8-) <br>
<br>
When ever you reference another component from your component, for example <br>
including a TDataSource property in your component, you should override the <br>
Noficication method and respond to it by checking that the component you are <br>
referencing is not being deleted. You should also use the FreeNotification <br>
method to ensure that you are notified even it the TComponent you are <br>
referencing is in another module. By default you only recieve notifications <br>
of componets in the same module as your component has been placed, and now <br>
that Borland has provided data modules you are sure to run this case more <br>
often than you expect. <br>
<br>
If you don't use the Nofification method you will find (as I did) that <br>
ll find (as I did) that <br>
deleting a component that you reference will place the Delphi IDE into an <br>
extremely unstable state. It doesn't quite crash, but its very hard to do <br>
anything afterwards. <br>
<br>
Here is an example showing just the critical methods with a single reference <br>
to another component: <br>
<br>
type <br>
TMyComponent = class(TComponent) <br>
private <br>
FDataSource: TDataSource; <br>
procedure SetDataSource(Value: TDataSource); <br>
protected <br>
procedure Notification(AComponent: TComponent; Operation: TOperation); <br>
override; <br>
published <br>
property DataSource: TDataSource read FDataSource write SetDataSource; <br>
end; <br>
<br>
procedure TMyComponent.SetDataSource(Value: TDataSource); <br>
begin <br>
if Value <> FDataSource then <br>
if Value <> FDataSource then <br>
begin <br>
FDataSource := Value; <br>
if FDataSource <> nil then <br>
// Tell the component that we are interested in its fate <br>
FDataSource.FreeNotification(Self) <br>
end <br>
end; <br>
<br>
procedure TMyComponent.Notification(AComponent: TComponent; <br>
Operation:TOperation); <br>
begin <br>
inherited Notification(AComponent, Operation); <br>
<br>
// If this is the component we are referencing then remove our reference <br>
if (Operation = opRemove) and (AComponent = FDataSource) then <br>
FDataSource := nil <br>
end; <br>
<br>
5.3. What are component messages? <br>
<br>
Component messages are used much like regular Windows messages except that they <br>
are used for notification of events that are only applicable to Delphi component <br>
s. If you have a component that publishes the Font property the component proba <br>
bly needs to be repainted if any subproperties in the Font are changed. Changin <br>
g the Font property does not necessarily generate a Windows event but the contro <br>
l still needs to know about the change. Component messages serve this purpose. <br>
<br>
It appears that virtual methods could have been used in place of component messa <br>
ges. Presumably messages are used in order to keep the size of the virtual disp <br>
atch table from getting out of hand. <br>
<br>
The books "Secrets of Delphi 2.0" has descriptions for the individual component <br>
messages. <br>
<br>
This is a listing of some of the component messages andwhat they do. The messag <br>
es marked "Notification Only" do not pass any useful information to the message <br>
handler and do not expect the message handler to return a value. <br>
<br>
CM_ACTIVATE (Notification Only) <br>
A form sends itself this message is sent to a form when it becomes the active fo <br>
rm. <br>
<br>
CM_CTL3DCHANGED (Notification Only) <br>
A control sends itself this messsage when its CTL3D Property changes. <br>
A control sends itself this messsage when its CTL3D Property changes. <br>
<br>
CM_DESIGNHITTEST <br>
Parameters: TCMDesignHitTest <br>
Return Value: Appears to be either zero or one. <br>
This message is sent in design mode when the mouse is over the control. It appe <br>
ars that the purpose of the message is to determine if the control wants to proc <br>
ess mouse messages while in design mode. If the return value is one then Delphi <br>
lets the control process mouse messages. If it is zero then the Delphi handles <br>
the messages. If a control sets this message to one all the time then the popup <br>
menu will never appear. If the control does not handle this message or returns <br>
zero all the time then the control cannot response to mouse messages in design <br>
mode. <br>
<br>
CM_FONTCHANGED (Notification Only) <br>
Sent to a control when the control's font is changed. <br>
<br>
CM_FONTCHANGE (Notification Only) <br>
A controls sends this message to itself when it receives a WM_FONTCHANGE message <br>
. <br>
<br>
CM_PARENTCTL3DCHANGED (Notification Only) <br>
Sent to all child controls when a parent (not Owner) receives a CM_CTL3DCHANGED <br>
message. This message is also send when the control is gets a new parent. <br>
<br>
CM_PARENTCOLORCHANGED (Notification Only) <br>
A Control sends this message to itself when the value of its ParentColor propert <br>
y changes. This message is also send when the control is read from a stream or g <br>
ets a new parent. <br>
<br>
CM_PARENTFONTCHANGED (Notification Only) <br>
Sent to all child controls when a parent (not Owner) receives a CM_FONTCHANGED m <br>
essage. This message is also send when the control is read from a stream or gets <br>
a new parent. <br>
<br>
CM_PARENTSHOWHINTCHANGED (Notification Only) <br>
A Control sends this message to itself when the value of its ParentShowHint prop <br>
erty changes. This message is also send when the control is read from a stream o <br>
r gets a new parent. <br>
<br>
CM_WININICHANGE <br>
Parameters: Same as for WM_WININICHANGE <br>
Return Value: None <br>
A control sends itself this message when it receives a WM_WININICHANGE message. <br>
<br>
<br>
5.4. My control has focus but it is not gettig keystoke messages. What's happen <br>
ing? <br>
<br>
If you have published the DragMode property and it is set to dmAutomatic it is p <br>
ossible for your control to get in a state where it thinks it is dragging but it <br>
really is not. The CONTROLS.PAS module has a module local variable called Drag <br>
Control that is a reference to the control currently being dragged. Under certa <br>
in conditions it is possible for this variable to not get cleared even though a <br>
drag operation is not underway. The WndProc procedure to TWinControls ignores k <br>
eystroke messages for a control when it thinks dragging is underway. <br>
<br>
<br>
------------------------------------------------------------------------ <br>
Section 6 - Other Sources of Information <br>
<br>
6.1. Are there any books on how to write Delphi components? <br>
<br>
The book that has become the standard for writing components is: <br>
<br>
"Developing Delphi Components" by Ray Konopka, Coriolis Group Books <br>
<br>
While this book not specifically on how to write components it has a lot of info <br>
rmation that is invaluable to the component writer: <br>
<br>
"Secrets of Delphi 2" by Ray Lischner, Waite Group Press <br>
<br>
Another book on writing components that has information not found in Konopka's b <br>
ook is <br>
<br>
"Programming Delphi Custom Components" by Fred Bulback, M&T Books <br>
<br>
6.2. Are there any good web sites with information on how to write components? <br>
<br>
The largest Delphi web site is "The Delphi Super Site" at <br>
<br>
http://sunsite.icm.edu.pl/~robert/delphi <br>
<br>
This page has links to many other Delphi sites. <br>
<br>
I have found Component source code on the following sites as well: <br>
<br>
http://www.coast.net/~jkeller <br>
http://www.pobox.com/~bstowers/delphi <br>
<br>
<br>
You can also find Delphi sites by using: <br>
<br>
Yahoo: www.yahoo.com <br>
Alta Vista: www.altavista.digital.com <br>
<br>
Unfortunately Web sites have a nasty habit of disappearing or moving. Please no <br>
tify the maintainer these addresses are out of date. <br>
<br>
------------------------------------------------------------------------ <br>
Section 7 - Persistant Objects <br>
<br>
7.1. How can I save a complex object containing child objects to the .DFM file. <br>
<br>
I have tried all sorts of schemes using DefineProperties and WriteComponents and <br>
they all failed to work. As far as I can tell the only way to do this is to use <br>
Delphi's default mechanism to store your child objects. <br>
<br>
A sequence that does work for saving to a stream is: <br>
<br>
1. Make all of the classes whose objects you want to save descend from TComponen <br>
t. <br>
2. Make all of the values you want to save published. <br>
3. Within your Register procedure add a call to RegisterComponents containing al <br>
l of the classes you wish to store. <br>
4. Each class that owns child classes needs to overload the procedure GetChildre <br>
n. This procedure is needs to call the procedure passed as an argument for each <br>
child to be stored. (For Delphi V1 you need to override the WriteComponents meth <br>
od and call WriteComponent for each child.) <br>
<br>
<br>
Procedure TMyComponent.GetChildren (Proc : TGetChildProc) ; <br>
Begin <br>
Proc (Child1) ; <br>
Proc (Child2) ; <br>
<br>
Proc (Childn) ; <br>
End ; <br>
<br>
Getting the objects out of the stream is a little trickier. Your parent object <br>
may need to overload the GetChildOwner and GetChildParent functions. Otherwise <br>
Delphi will try to make the child owned by the form. (In Delphi V1 you need to o <br>
verride the Readstate method.) <br>
<br>
7.2. How can I tell if my contructor is being called for an object being loaded <br>
contructor is being called for an object being loaded <br>
from a stream? <br>
<br>
csLoading is not set in ComponentState until immediately after the component is <br>
created. However the component's owner will already have this set so try <br>
<br>
Constructor TMyClass.Create (AOwner : TComponent) ; <br>
Begin <br>
If csLoading in AOwner.ComponentState Then <br>
Begin <br>
End <br>
Else <br>
Begin <br>
End ; <br>
End ; <br>
<br>
7.3. How can I tell if my component's properties are being saved correctly to th <br>
e form file? <br>
<br>
There are a couple of easy ways to view properties as they are stored in the for <br>
m file: <br>
<br>
1. From design mode in Delphi use click the left mouse button over a form contai <br>
on over a form contai <br>
ning your component the select "View as Text". Unfortunately if there are any e <br>
rrors in the form file you will not see anything. <br>
<br>
2. From the DOS prompt run the CONVERT program that comes with Delphi. <br>
<br>
Stefan Hoffmeister points out that if you copy a control the the clipboard then <br>
you can paste the text representation of the control to an editor such Notepad. <br>
You can edit the control in the editor and paste it back into to your Delphi app <br>
lication. <br>
<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -