I have a string variable s: ARRAY 64 OF CHAR; and would like to copy its contents to the clipboard.
It is a 0X terminated string.
How do do it inside a Component Pascal Program?
Thank you very much for any help.
Helmut
How to copy a string to the clipboard?
-
- Posts: 262
- Joined: Tue Sep 17, 2013 6:50 am
Re: How to copy a string to the clipboard?
I do it in the following way:
- Josef
Code: Select all
PROCEDURE CopyToClipboard(IN str: ARRAY OF CHAR);
VAR i: INTEGER; T: TextModels.Model; W: TextModels.Writer;
BEGIN
T := TextModels.dir.New();
W := T.NewWriter(NIL);
FOR i := 0 TO LEN(str$) DO W.WriteChar(str[i]) END ;
HostClipboard.Register(TextViews.dir.New(T), 0, 0, FALSE)
END CopyToClipboard;
Re: How to copy a string to the clipboard?
Josef, thank you very much. It works perfectly. Helmut
Re: How to copy a string to the clipboard?
What about Paste, i.e. read the content stored in the clipboard?
I have tried two versions:
At first I felt a bit unable to decide which interface was better, whether a or b:
a) PROCEDURE PasteFromClipboard* (): POINTER TO ARRAY OF CHAR
b) PROCEDURE PasteFromClipboard* (OUT str: ARRAY OF CHAR)
Interface "a" seems more usable because can be called directly even without having a destination array, e.g.:
Also it is fine that the client does not need to worry about the size of the array, but ... caution should be taken if the clipboard has got a large amount of data; otherwise execution traps with "stack overflow" or "illegal memory write". I also have noticed that if the clipboard, instead of chars, has got a file, then there is no problem because HostClipboard.GetClipView gives value NIL to variable v, and nothing is returned.
I reckon that interface "b" can be more efficient because the procedure does not need to allocate the array, but a truncation will be produced if the content of the clipboard is greater than the VAR parameter received.
Because of the possible traps, I favour "b" over "a".
On the other hand ... the client can be interested in reading the content of the clipboard in other ways, rather than as bare chars. I mean, he might want to read the list of numbers stored in the clipboard, for example. In that case, to read the clipboard it is better to use "S.Scan, S.type and S.int", instead of "S.rider.ReadChar(ch)".
What I want to say is that the above procedure PasteFromClipboard (returning chars) is not a general utility function, and that the client will have to write his ad hoc procedure to read the clipboard.
Anyway, it is useful to have at hand a procedure like PasteFromClipboard (returning chars), because it gives clues about how to read the clipboard.
Regards
I have tried two versions:
Code: Select all
PROCEDURE PasteFromClipboard* (): POINTER TO ARRAY OF CHAR;
VAR i: INTEGER; T: TextModels.Model; S: TextMappers.Scanner;
v: Views.View; w, h: INTEGER; isSingle: BOOLEAN;
str: POINTER TO ARRAY OF CHAR; ch: CHAR;
BEGIN
HostClipboard.GetClipView("", v, w, h, isSingle);
IF (v # NIL) & (v.ThisModel() # NIL) & (v.ThisModel() IS TextModels.Model) THEN
(* Views.OpenView(v); *)
T := v.ThisModel()(TextModels.Model);
S.ConnectTo(T);
NEW(str, T.Length() + 1);
i := 0; S.rider.ReadChar(ch);
WHILE ~S.rider.eot DO
IF S.rider.view = NIL THEN str^[i] := ch; INC(i) END;
S.rider.ReadChar(ch)
END;
str^[i] := 0X
ELSE
NEW(str, 1); str^[0] := 0X
END;
RETURN str
END PasteFromClipboard;
PROCEDURE PasteFromClipboard* (OUT str: ARRAY OF CHAR);
VAR i: INTEGER; T: TextModels.Model; S: TextMappers.Scanner;
v: Views.View; w, h: INTEGER; isSingle: BOOLEAN;
ch: CHAR;
BEGIN
HostClipboard.GetClipView("", v, w, h, isSingle);
IF (v # NIL) & (v.ThisModel() # NIL) & (v.ThisModel() IS TextModels.Model) THEN
(* Views.OpenView(v); *)
T := v.ThisModel()(TextModels.Model);
S.ConnectTo(T);
i := 0; S.rider.ReadChar(ch);
WHILE (i < LEN(str) - 1) & ~S.rider.eot DO
IF S.rider.view = NIL THEN str[i] := ch; INC(i) END;
S.rider.ReadChar(ch)
END;
str[i] := 0X
ELSE
str[0] := 0X
END
END PasteFromClipboard;
a) PROCEDURE PasteFromClipboard* (): POINTER TO ARRAY OF CHAR
b) PROCEDURE PasteFromClipboard* (OUT str: ARRAY OF CHAR)
Interface "a" seems more usable because can be called directly even without having a destination array, e.g.:
Code: Select all
StdLog.String("Content = '" + PasteFromClipboard() + "'")
I reckon that interface "b" can be more efficient because the procedure does not need to allocate the array, but a truncation will be produced if the content of the clipboard is greater than the VAR parameter received.
Because of the possible traps, I favour "b" over "a".
On the other hand ... the client can be interested in reading the content of the clipboard in other ways, rather than as bare chars. I mean, he might want to read the list of numbers stored in the clipboard, for example. In that case, to read the clipboard it is better to use "S.Scan, S.type and S.int", instead of "S.rider.ReadChar(ch)".
What I want to say is that the above procedure PasteFromClipboard (returning chars) is not a general utility function, and that the client will have to write his ad hoc procedure to read the clipboard.
Anyway, it is useful to have at hand a procedure like PasteFromClipboard (returning chars), because it gives clues about how to read the clipboard.
Regards
Re: How to copy a string to the clipboard?
How is it possible that module HostPictures uses HostClipboard.len, if len does not exist in module HostClipboard?
- Ivan Denisov
- Posts: 362
- Joined: Tue Sep 17, 2013 12:21 am
- Location: Krasnoyarsk, Russia
Re: How to copy a string to the clipboard?
This part of code in HostPictures is commented.manumart1 wrote:How is it possible that module HostPictures uses HostClipboard.len, if len does not exist in module HostClipboard?
Re: How to copy a string to the clipboard?
Thank you, I didn't see it.
I think that putting in green colour the commented out lines is a good idea.
I usually use CpcBeautifier, but I like to have the "Ident Check" on, and therefore the ident of the commented out block is destroyed, which is not nice:
PROCEDURE ImportC*;
VAR v: StdView; pic: MemoryMgr.Handle; s, d, len: LONGINT; ch: CHAR;
BEGIN
len := HostClipboard.len;
pic := MemoryMgr.NewHandle(len); MemoryMgr.HLock(pic);
s := HostClipboard.adr; d := SYSTEM.ADR(pic^);
WHILE len # 0 DO
SYSTEM.GET(s, ch); SYSTEM.PUT(d, ch); INC(s); INC(d); DEC(len)
END;
NEW(v); v.Init;
v.model := NewModel(SYSTEM.VAL(QuickDraw.PicHandle, pic));
HostClipboard.view := v
END ImportC;
I think that putting in green colour the commented out lines is a good idea.
I usually use CpcBeautifier, but I like to have the "Ident Check" on, and therefore the ident of the commented out block is destroyed, which is not nice:
PROCEDURE ImportC*;
VAR v: StdView; pic: MemoryMgr.Handle; s, d, len: LONGINT; ch: CHAR;
BEGIN
len := HostClipboard.len;
pic := MemoryMgr.NewHandle(len); MemoryMgr.HLock(pic);
s := HostClipboard.adr; d := SYSTEM.ADR(pic^);
WHILE len # 0 DO
SYSTEM.GET(s, ch); SYSTEM.PUT(d, ch); INC(s); INC(d); DEC(len)
END;
NEW(v); v.Init;
v.model := NewModel(SYSTEM.VAL(QuickDraw.PicHandle, pic));
HostClipboard.view := v
END ImportC;