4

I'm going to admit, right off the bat, that I'm Pascal-inexperienced, to say the least. So, any help I can get will be greatly appreciated. :)

As part of a larger program, I need to write a string variable to the clipboard. I've created a new project in Lazarus (version 1.0.12) so I can try to figure out how to do so without the complications caused by extra, unnecessary code, which I have included below:

program varToClipboard;

uses Clipbrd;

var
    textToCopy:string;

begin
    textToCopy := 'Test text from Pascal';

    Clipboard.AsText := textToCopy;
end.  

Using the above code, along with a required LCLBase dependency, I'm getting the following error in CMD when running the compiled EXE:

An unhandled exception occurred at $000000000043D45E :
EAccessViolation : Access violation
  $000000000043D45E  CLIPBOARDREGISTERFORMAT,  line 98 of ./include/lclintf.inc
  $000000000043C35B  PREDEFINEDCLIPBOARDFORMAT,  line 185 of lclintf.pas
  $0000000000415B0C  TCLIPBOARD__SETASTEXT,  line 452 of ./include/clipbrd.inc
  $0000000000401802  main,  line 12 of varToClipboard.lpr

According to the documentation, I seem to be doing everything right. Although, I have found the documentation to be... lacking on more than on occasion.

 

Also, what do I have to do so that I can run the compiled EXE (which will just generate and write a string to the clipboard) without the console window popping up?

mythofechelon
  • 3,692
  • 11
  • 37
  • 48

1 Answers1

5

You were doing it right. The problem here is that clipboard class doesn't somehow encount to be used in console applications. Your application failed on the following line from the lclintf.inc file, where the WidgetSet object is going to be accessed. That fails because the WidgetSet variable is nil while you're in console application just because console application doesn't need any widgets:

function ClipboardRegisterFormat(const AMimeType: string): TClipboardFormat;
begin
  Result := WidgetSet.ClipboardRegisterFormat(AMimeType);
end;

To workaround this you may add the Interfaces unit to your uses clause and add the LCL package dependency to your project:

program Project1;

uses
  Clipbrd,
  Interfaces;

begin
  Clipboard.AsText := 'Hello, I''m a text from clipboard!';
end.

But according to your additional question it seems that you want to make the application, which will just copy certain text to the clipboard and terminates. That's what the console application type is not a right choice because of that console window shown for a short time. For that sort of application I would make the formless window application (please note that I know this trick only from Windows platform):

  1. Create a new application through menu File / New..., select Project / Application in the dialog's tree view and create a new project by clicking OK
  2. Now let's remove the only unit (with a form) from your project; go to the menu Project / Remove from Project and in the newly opened dialog select unit1.pas and click OK
  3. Now you have a unitless (and formless) application, so what remains is to write a code to copy the text to the clipboard; so now let's open the project source from menu Project / View Project Source and as the project source paste a code like this (this is the shortest possible form):

program Project1;

uses
  Interfaces, Forms, Clipbrd;

begin
  Application.Initialize;
  Clipboard.AsText := 'Hello, I''m a text from clipboard!';
end.
TLama
  • 75,147
  • 17
  • 214
  • 392