Re: OpenPictureDialog Problems
- From: Rob Kennedy <me3@xxxxxxxxxxx>
- Date: Sat, 23 Jul 2005 04:48:33 -0500
Henry Bartlett wrote:
<cybatech@xxxxxxxxxxxxx> .wrote..Sorry for being so vague. When I run it I get Acces Violation.
Here is your first problem
You have
procedure TForm1.SpeedButton2Click(Sender: TObject); var NewShape : TManyShape; begin NewShape := TManyShape.Create(self);
Here NewShape is a local variable and has meaning only within the SpeedButton2Click method.
When the SpeedButton2Click method concludes "NewShape" ceases to have any meaning and is lost in the wide blue yonder.
And so all you are left with is a memory leak.
Wrong. NewShape is indeed a local variable, but that isn't the only reference to the control. In the line you quoted, there will also be a reference to the control added to the form's Components array. In the code you didn't quote, there is a line assigning NewShape.Parent := Self, which creates yet another reference to the control, this time in the form's Controls array.
Since the new control's mouse events have been assigned, a reference to the control will also be available in those events' Sender parameters.
When the form gets freed, it will free all the components it owns, including whatever TManyShape controls that these button-click events have generated, so there's no leak.
And in the Button1Click method you declare another local variable named NewShape which only has meaning within *this* method,
That in itself isn't a problem. A big clue to the problem is the compiler warning that Cy has chosen to _ignore_ regarding whether NewShape has been initialized. The real problem is that no one has specified *which* shape control this button is supposed to be acting upon. Once that's decided, a reference to that control can be stored into the local NewShape variable and the code can proceed normally.
procedure TForm1.Button1Click(Sender: TObject); var OpenPicDlg : TOpenPictureDialog; Bitmap: TBitmap; NewShape : TManyShape;
If you want a variable to be visible within more than one method, declare it as a private class variable (e.g. fNewShape).
But you are creating a whole lot of shapes aren't you? Then you can't keep using the same name. The simplest way is to use a list or an array of tManyShapes and add the shapes as you create them.
In the TForm1.Button1Click method use the Sender parameter so that your program knows which shape has been clicked on
procedure TForm1.Button1Click(Sender: TObject); var OpenPicDlg : TOpenPictureDialog; // Bitmap: TBitmap; no need for this line, it just confuses things NewShape : TManyShape; // NewShape is local alias begin NewShape := Sender as TManyShape;
The Sender will never be a TManyShape because Button1Click hasn't been assigned to any TManyShape event handlers. Button1Click is the event handler for a button. (Cy would do well to get into the habit of giving his controls _meaningful_ names!)
OpenPicDlg := TOpenPictureDialog.Create(Self); Try if OpenPicDlg.Execute then NewShape.Image.Picture.Bitmap.LoadFromFile(OpenPicDlg.FileName); // watch the wrap and see note * below finally OpenPicDlg.Free end; end;
end
* Note
Your lines
bitmap.LoadFromFile(OpenPicDlg.FileName); Newshape.Image :=Bitmap;
really confuse me
What is the type of the objects you are loading from file?
From your code it looks as though they may be tBitmaps.
The fact that the "bitmap" variable is declared as a TBitmap should be a dead giveaway. :)
If TManyShape is written properly, then there is probably a memory leak in this code. The Image property should have a setter method implemented like this:
procedure TManyShape.SetImage(const Value: TBitmap); begin FImage.Assign(Value); end;
Since the shape control does not retain a reference to the new bitmap -- it just copies the contents into the graphic it already has -- the code that assigns the property needs to free the bitmap. Better yet, the code can just tell the shape to load the image file itself and skip the temporary bitmap object:
NewShape.Image.LoadFromFile(OpenPicDlg.FileName);
I am not familiar with TManyShape but it sounds as though it is a descendant of the TShape.component.
Does TManyShape have a property named Image?
If it does then I suspect that it is of type TImage.
Unlikely. If TManyShape descends from TShape, then it is a TGraphicControl, which cannot have child controls. On the other hand, I have seen folks use TImage as an unseen graphic holder instead of using the more lightweight TPicture or TGraphic classes. If this were my control, the property would be a TPicture, and its name would be Picture, not Image.
If this is so then tManyShape.Image is not compatible with tBitmap.
I'm pretty sure the code we've seen compiles, which means the Image property is TGraphic or TBitmap, not TImage.
-- Rob .
- Follow-Ups:
- Re: OpenPictureDialog Problems
- From: Henry Bartlett
- Re: OpenPictureDialog Problems
- References:
- OpenPictureDialog Problems
- From: cybatech
- Re: OpenPictureDialog Problems
- From: Maarten Wiltink
- Re: OpenPictureDialog Problems
- From: cybatech
- Re: OpenPictureDialog Problems
- From: Henry Bartlett
- OpenPictureDialog Problems
- Prev by Date: Re: TMemo: How can i get the caret x/y pos. into client x/y pos. ?
- Next by Date: Re: Strange problem with delphi application on Citrix Metaframe
- Previous by thread: Re: OpenPictureDialog Problems
- Next by thread: Re: OpenPictureDialog Problems
- Index(es):