direktor05 2 Posted July 26 Hello, I have TCanvas and I want to dynamically add onClick event. How do I do that? I read something about TNotify and adding property, but how exactly? Need whole code. Share this post Link to post
Lajos Juhász 270 Posted July 26 It is TNotifyEvent = procedure(Sender: TObject) of object; To assign a value OnClick event you have to create a method with this signature. For example: type TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); procedure DoSomethingClick(Sender: TObject); // Event handler for an OnClick private { Private declarations } public { Public declarations } end; Then you can write in your code: procedure TForm1.FormCreate(Sender: TObject); begin Image1.OnClick:=DoSomethingClick; end; Share this post Link to post
direktor05 2 Posted July 26 Only one problem. Image1 has onClick event by default. TCanvas does not have it. So I need to add property I think. Its a little bit more complicated. Share this post Link to post
Lajos Juhász 270 Posted July 26 you cannot do add a property to a class that doesn't have it. Share this post Link to post
FPiette 377 Posted July 26 TCanvas is a kind of API for a drawing surface. It encapsulate drawing primitives like line or text. A TCanvas is a property of some other graphics component, for example an image component. This is at that component level that you must handle onClick. This being said, you should better explain what you need and what you already have, preferable with some code sample. If you explain correctly, chaces are that you get a helpful answers. Share this post Link to post
Kas Ob. 109 Posted July 26 2 hours ago, direktor05 said: TCanvas does not have it. Well, as Francois said it, and i will elaborate a little on that. TCanvas is Delphi/Pascal RTL encapsulation for Device Context: https://learn.microsoft.com/en-us/windows/win32/gdi/device-contexts https://learn.microsoft.com/en-us/windows/win32/gdi/about-device-contexts These are Output devices and has no Input, and by Input i mean there is no hardware user input or interaction, their input is solemnly comes from drawing APIs, and in other words they are GDI drawing object that simulate a painting canvas (real life canvas) to be processed further, like to be rendered on monitor or to be passed to printer.... they are build that way to unify User mode GDI and supply one Interface to different hardware, their functionalities differ based on what the hardware and its driver support, while the interface is the same for them all. Share this post Link to post
PeterBelow 231 Posted July 26 4 hours ago, direktor05 said: Hello, I have TCanvas and I want to dynamically add onClick event. How do I do that? I read something about TNotify and adding property, but how exactly? Need whole code. You don't. Use a TPaintbox as a drawing surface, it has a Canvas and an OnClick event. TImage is another candidate, it contains (by default) a bitmap you can draw on using the image component's Canvas, and it also has an OnClick event. As explained in other replies a TCanvas is just a wrapper for a window's device context, it cannot receive mouse events directly. Share this post Link to post
direktor05 2 Posted July 31 On 7/26/2024 at 6:55 PM, PeterBelow said: You don't. Use a TPaintbox as a drawing surface, it has a Canvas and an OnClick event. TImage is another candidate, it contains (by default) a bitmap you can draw on using the image component's Canvas, and it also has an OnClick event. As explained in other replies a TCanvas is just a wrapper for a window's device context, it cannot receive mouse events directly. Exactly! But I need only the top 100px of that paintbox to be able to be clicked to trigger a specific event not whole TPaintBox - or other areas of painbox that are filled with other things. How can I achieve that? Share this post Link to post
direktor05 2 Posted July 31 2 minutes ago, direktor05 said: Exactly! But I need only the top 100px of that paintbox to be able to be clicked to trigger a specific event not whole TPaintBox - or other areas of painbox that are filled with other things. How can I achieve that? like the picture shows. Share this post Link to post
Pat Foley 51 Posted July 31 (edited) procedure TForm23.PaintBox1Click(Sender: TObject); begin if Mouse.CursorPos.Y > 100 then exit; end; procedure TForm23.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Y < 100 then dostuff end; Try an OnMouseOver event and perhaps a PtinRect for the cursor's xy position. Edited July 31 by Pat Foley Added sample Share this post Link to post
Remy Lebeau 1330 Posted July 31 3 hours ago, Pat Foley said: procedure TForm23.PaintBox1Click(Sender: TObject); begin if Mouse.CursorPos.Y > 100 then exit; end; Mouse.CursorPos is expressed in screen coordinates, not client coordinates. You would need to use PaintBox1.ScreenToClient() in this case: procedure TForm23.PaintBox1Click(Sender: TObject); begin if PaintBox1.ScreenToClient(Mouse.CursorPos).Y > 100 then Exit; // do something... end; Share this post Link to post
Pat Foley 51 Posted July 31 1 hour ago, Remy Lebeau said: Mouse.CursorPos is expressed in screen coordinates, not client coordinates. You would need to use PaintBox1.ScreenToClient() in this case: Oops! Should stuck with mouseover events to allow a "Proper" FocusRect to be drawn when over the area or subtracted the Control's ClientOrigin.Y Share this post Link to post