Recent

Author Topic: Where is TRichMemoInlinePicture?  (Read 12354 times)

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Where is TRichMemoInlinePicture?
« on: September 18, 2021, 07:55:34 pm »
So looking through previous discussions it seems that in order to insert a picture into a RichMemo I need to pass InDelInline a TRichMemoInlinePicture. I can't find where this is defined (You'd have thought along with RichMemo but no) but I did find some suggested code for it. I stuck it in a unit (code below) but when I told the unit to compile it complained that it couldn't open a resource file rminlinepicture.lfm. This hasn't happened to me before and I don't understand it.

What's the latest advice on getting pictures to work in a RichMemo?

Thanks.

Code: Pascal  [Select][+][-]
  1. unit RMInlinePicture;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, RichMemo, Graphics, Types;
  9.  
  10. type
  11.  
  12.   { TRichMemoInlinePicture }
  13.  
  14.   TRichMemoInlinePicture = class(TRichMemoInline)
  15.     pic: TPicture;
  16.     constructor Create(Apicture: TPicture);
  17.     procedure Draw(Canvas: TCanvas; const ASize: TSize); override;
  18.   end;
  19.  
  20. implementation
  21.  
  22. {$R *.lfm}
  23.  
  24. { TRichMemoInlinePicture }
  25.  
  26.   constructor TRichMemoInlinePicture.Create(Apicture: TPicture);
  27.   begin
  28.     inherited Create;
  29.     pic:=APicture;
  30.   end;
  31.  
  32.   procedure TRichMemoInlinePicture.Draw(Canvas: TCanvas; const ASize: TSize);
  33.   begin
  34.     inherited Draw(Canvas, ASize);
  35.     Canvas.Draw(0,0, pic.Graphic);
  36.   end;
  37.  
  38. end.
« Last Edit: September 18, 2021, 07:58:57 pm by Spoonhorse »

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #1 on: September 19, 2021, 03:59:15 pm »
Well the unit was behaving like that because of the {$R *.lfm} thing that got in there somehow. I shouldn't try to debug when tired. I have some very nearly working code, will report back soon.

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #2 on: September 19, 2021, 05:02:45 pm »
Well, I still have nearly-working code. It will insert pictures into the text without complaint, but when it comes to *display* the memo it crashes with a SIGSEGV complaint. It does this even if I comment out the contents of the draw method so it doesn't do anything.

At this point I'm at a loss, does anyone know the authors? Or anyone who's successfully managed to make it work?

Since I know I can paste pictures into the text from the clipboard, there might be a way around it by essentially getting my app to do that. But it's terrible clumsy.
« Last Edit: September 19, 2021, 05:36:54 pm by Spoonhorse »

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1090
  • Professional amateur ;-P
Re: Where is TRichMemoInlinePicture?
« Reply #3 on: September 19, 2021, 06:29:13 pm »
Hey SpoonHorse,

This is just  suggestion from a person that has not had a look at any code from either TRichMemo or anything related, but if the component is able to do it on the paste event, I would have a look at that particular region of the code and see how it does it.

I'm sorry I can't pitch in with something more substantial, but that's how I'd go about solving this problem.

Hope this can give you another avenue of enlightenment :)

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #4 on: September 19, 2021, 10:03:38 pm »
Well I would but I can't figure out how. If I open up RichMemo I can find where it says procedure PasteFromClipboard; override; but there's no clue as to where the implementation is. So as far as I know it's done by magic. How does that even work?

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 1090
  • Professional amateur ;-P
Re: Where is TRichMemoInlinePicture?
« Reply #5 on: September 19, 2021, 10:43:53 pm »
Hey SpoonHorse,

Well I would but I can't figure out how. If I open up RichMemo I can find where it says procedure PasteFromClipboard; override; but there's no clue as to where the implementation is. So as far as I know it's done by magic. How does that even work?

Let me introduce you to one very nifty keyboard shortcut: Ctrl+Shift+Up.

If you place the cursor on the Interface declaration of the class procedure and press that shortcut, the IDE will send you to the Implementation of said procedure, if and only if it can locate the file where it is.

Hope that helps!!

Cheers,
Gus
Lazarus 3.99(main) FPC 3.3.1(main) Ubuntu 23.10 64b Dark Theme
Lazarus 3.0.0(stable) FPC 3.2.2(stable) Ubuntu 23.10 64b Dark Theme
http://github.com/gcarreno

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #6 on: September 20, 2021, 08:57:01 am »
Thanks. Well, I thought that knowledge would open up all sorts of things to me but no.

I tried that, I got this.

Code: Pascal  [Select][+][-]
  1. procedure TCustomRichMemo.PasteFromClipboard;  
  2. begin
  3.   if HandleAllocated then  
  4.     TWSCustomRichMemoClass(WidgetSetClass).PasteFromClipboard(Self);
  5. end;

OK, let's find where *that* PasteFromClipboard is defined:

Code: Pascal  [Select][+][-]
  1. class procedure PasteFromClipboard(const AWinControl: TWinControl); virtual;

It's another interface. Fair enough. Let's follow that method up with Ctrl + Shift + Up.

Code: Pascal  [Select][+][-]
  1. class procedure TWSCustomRichMemo.PasteFromClipboard(const AWinControl: TWinControl);
  2. begin
  3.  
  4. end;

Oh look, it's completely empty.

At this point I look up the word "virtual".

"A virtual method is a type of method where the actual method calls depends on the runtime type of the underlying object."

But ... where is the code? I am only a simple code monkey but when I write code it does something. This is just a maze. Where is the thing that does the thing?

dsiders

  • Hero Member
  • *****
  • Posts: 1045
Re: Where is TRichMemoInlinePicture?
« Reply #7 on: September 20, 2021, 03:33:11 pm »
"A virtual method is a type of method where the actual method calls depends on the runtime type of the underlying object."

But ... where is the code? I am only a simple code monkey but when I write code it does something. This is just a maze. Where is the thing that does the thing?

Use the file search utilities for your OS. Find or FindStr on Windows. grep on linux. I have a copy of CygWin on my windows machine just for the utilities.

Code: Bash  [Select][+][-]
  1. grep -i --include=*.{pas,pp,inc} --recursive .
  2. lcl/grids.pas:procedure TCustomGrid.DoPasteFromClipboard;
  3. lcl/grids.pas:procedure TCustomStringGrid.DoPasteFromClipboard;
  4. lcl/groupededit.pp:procedure TCustomAbstractGroupedEdit.PasteFromClipboard;
  5. lcl/include/customedit.inc:procedure TCustomEdit.PasteFromClipboard;
  6. lcl/include/dbimage.inc:procedure TDBImage.PasteFromClipboard;
  7. lcl/lclmessageglue.pas:function LCLSendPasteFromClipboardMsg(const Target: TControl): PtrInt;
  8. lcl/maskedit.pp:procedure TCustomMaskEdit.PasteFromClipBoard;
  9. lcl/stdctrls.pp:    procedure PasteFromClipboard; virtual;
  10.  
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #8 on: September 20, 2021, 04:46:54 pm »
OK, but ... is that really the only way in? Search for mentions of it, pick out the right one by hand? How does the compiler know how to find the implementation of a method declared like that? Why can't I find it like the compiler does?

zoltanleo

  • Sr. Member
  • ****
  • Posts: 486
Re: Where is TRichMemoInlinePicture?
« Reply #9 on: September 20, 2021, 10:58:46 pm »
At this point I'm at a loss, does anyone know the authors?
Hi Spoonhorse.

Try to write to the author of this component
https://forum.lazarus.freepascal.org/index.php?action=profile;u=13884
Win10 LTSC x64/Deb 11 amd64(gtk2/qt5)/Darwin Cocoa (Monterey):
Lazarus x32/x64 2.3(trunk); FPC 3.3.1 (trunk), FireBird 3.0.10; IBX by TonyW

Sorry for my bad English, I'm using translator ;)

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Where is TRichMemoInlinePicture?
« Reply #10 on: September 21, 2021, 02:18:00 am »
But ... where is the code? I am only a simple code monkey but when I write code it does something. This is just a maze. Where is the thing that does the thing?
...
Why can't I find it like the compiler does?
it's not a maze, but an amazing back bone of LCL, known as VMT-hack. It's a very old solution (back from the days when FPC didn't support interfaces), that still works.
And in fact, the compiler doesn't find the proper implementation as well.

What's happening is a run-time construction of an additional virtual class, with a mix of methods from different classes. The mix is driven by the hierarchy you're trying to search through (TWSCustomRichMemoClass -> TWSCustomMemo -> TWSCustomEdit)
However, the actual implementation is being copied over from a selected widgetset.
For Win32, you might want to search TWin32WSCustomRichMemoClass (from richmemo package), TWin32WSCustomMemo (from LCL), TWin32CustomEdit (from LCL).
(one of those should have PasteFromClipboard method)

The VMT for the virtual classes is reconstructed based on the inheritance of TWin32WSxxx classes. (the same thing is explained here)

However, once you find Win32 PasteFromClipboard you might find it pretty boring and uninteresting:
Code: Pascal  [Select][+][-]
  1. imptype procedure TWin32WSCustomEdit.Paste(const ACustomEdit: TCustomEdit);
  2. begin
  3.   SendMessage(ACustomEdit.Handle, WM_PASTE, 0, 0)
  4. end;
  5.  

In other words, all the "fun part" of actually pasting an image into a rich edit is implemented within the system code, and is not available for the review.

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #11 on: September 21, 2021, 05:35:42 am »
skalogryz, oh darn. Well at the very worst I could hijack the paste method, I could put whatever I want to insert on the clipboard and then send a message like that to paste it in. If I first store whatever's on the clipboard somewhere and then restore it. It's crude, but it should work.

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #12 on: September 21, 2021, 05:36:54 am »
zoltanleo, thanks, I may have to.

Spoonhorse

  • Full Member
  • ***
  • Posts: 123
Re: Where is TRichMemoInlinePicture?
« Reply #13 on: September 21, 2021, 09:39:32 am »
... wait, skalogryz is the author?

OK. In that case, skalogryz, instead of telling me how to peek into the class, can you just tell me how to get the InDelInline method to work so that I can delight my users? Thanks.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: Where is TRichMemoInlinePicture?
« Reply #14 on: September 21, 2021, 03:45:52 pm »
instead of telling me how to peek into the class, can you just tell me how to get the InDelInline method to work so that I can delight my users
are you users limited to Windows? Otherwise it won't work.

but when I told the unit to compile it complained that it couldn't open a resource file rminlinepicture.lfm
just get rid of {$R *.lfm} in rmInlinePicture.pas unit.
« Last Edit: September 21, 2021, 04:17:00 pm by skalogryz »

 

TinyPortal © 2005-2018