Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
>yes, this type of thing is why we use Pascal. pchar is your little bucket of ram that FPC in a sense knows nothing about. set it to #0 and pray for the best, cause that's what you do.. I'll just leave it with the #0, it doesn't seem to be hurting anything. Thanks to everyone for the help getting this to work. Here is what I ended up with if anyone is curious, or if someone comes across this doing a search. https://gist.github.com/Zaaphod/7d94e1d712a5b9ac2bcb0bc79f039a63 Also, here is my little console application I needed it for, just as a simple example on how to put the vertical column editing mode into the clipboard https://github.com/Zaaphod/Inches_To_Feet James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
I have my project working the way I want it to, but I have one little quirk I am hoping to fix. When I look at the clipboard, the entry for MSDEVColumnSelect has zero length. I’m not too familiar with PChars, but is there a way to set it to zero length? I set it to #0 and it works ok with the #0 in there with Notepadd++ but I think it’s technically not correct. Is there some way to call SetClipboardData(); to have it write just the format ID and zero length data? Here’s a code snip of the relevant section: EmptyClipBoard; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(p^,pp^,l+1); GlobalUnlock(h); res:=(SetClipboardData(CF_OEMTEXT,h)=h); h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); OemToCharBuffA(p,pp,l+1); SetClipboardData(CF_TEXT,h); GlobalUnlock(h); If Vertical then Begin q:=#0; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(q^,pp^,l+1); SetClipboardData(MSDEVColumnSelect,h); GlobalUnlock(h); q:=#2#0; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(q^,pp^,l+1); SetClipboardData(BorlandIDEBlockType,h); GlobalUnlock(h); End; James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
yes, this type of thing is why we use Pascal. pchar is your little bucket of ram that FPC in a sense knows nothing about. set it to #0 and pray for the best, cause that's what you do.. -- Alexander Grotewohl https://dcclost.com From: fpc-pascal on behalf of Jean SUZINEAU via fpc-pascal Sent: Friday, January 1, 2021 2:41:18 AM To: fpc-pascal@lists.freepascal.org Cc: Jean SUZINEAU Subject: Re: [fpc-pascal] GetClipboardFormatName causing an Error 216 Le 01/01/2021 à 00:48, James Richters via fpc-pascal a écrit : I’m not too familiar with PChars, but is there a way to set it to zero length? I set it to #0 and it works ok with the #0 in there with Notepadd++ but I think it’s technically not correct. For me, it's correct. C strings are just terminated with a null character, no notion of length, the length is not recorded in the string as in Pascal. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
Le 01/01/2021 à 00:48, James Richters via fpc-pascal a écrit : I’m not too familiar with PChars, but is there a way to set it to zero length? I set it to #0 and it works ok with the #0 in there with Notepadd++ but I think it’s technically not correct. For me, it's correct. C strings are just terminated with a null character, no notion of length, the length is not recorded in the string as in Pascal. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
I have my project working the way I want it to, but I have one little quirk I am hoping to fix. When I look at the clipboard, the entry for MSDEVColumnSelect has zero length. I’m not too familiar with PChars, but is there a way to set it to zero length? I set it to #0 and it works ok with the #0 in there with Notepadd++ but I think it’s technically not correct. Is there some way to call SetClipboardData(); to have it write just the format ID and zero length data? Here’s a code snip of the relevant section: EmptyClipBoard; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(p^,pp^,l+1); GlobalUnlock(h); res:=(SetClipboardData(CF_OEMTEXT,h)=h); h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); OemToCharBuffA(p,pp,l+1); SetClipboardData(CF_TEXT,h); GlobalUnlock(h); If Vertical then Begin q:=#0; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(q^,pp^,l+1); SetClipboardData(MSDEVColumnSelect,h); GlobalUnlock(h); q:=#2#0; h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1); pp:=pchar(GlobalLock(h)); move(q^,pp^,l+1); SetClipboardData(BorlandIDEBlockType,h); GlobalUnlock(h); End; James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
I don’t have Lazarus, just FPC, Thanks for the link. Thanks for the information, I understand how it works now. I appreciate the help. James From: fpc-pascal On Behalf Of Martin Frb via fpc-pascal Sent: Thursday, December 31, 2020 12:37 PM To: fpc-pascal@lists.freepascal.org Cc: Martin Frb Subject: Re: [fpc-pascal] GetClipboardFormatName causing an Error 216 On 31/12/2020 18:11, James Richters via fpc-pascal wrote: Thanks for the info on SynEdit. Where can I find the synedit source related to the clipboard? I think the link you indtended ater 'See the code at.' Didn't come though, can you pleaese send it again? Sorry, I assumed SynEdit would be recognized as part of Lazarus (yes its the fpc list, but the name may still be known). So I simply gave a file location in the Lazarus source. It can be found here: https://github.com/User4martin/lazarus/blob/master/components/synedit/syneditmiscclasses.pp#L1674 Some of the code is specific to SynEdit (E.g. information on code-folding). But ReadFromClipboard https://github.com/User4martin/lazarus/blob/master/components/synedit/syneditmiscclasses.pp#L1699 checks for either flag being present, and that is all you need. => Then the normal text, and line-ends in the text mark where each column ends. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
On 31/12/2020 18:11, James Richters via fpc-pascal wrote: Thanks for the info on SynEdit. Where can I find the synedit source related to the clipboard? I think the link you indtended ater 'See the code at.' Didn't come though, can you pleaese send it again? Sorry, I assumed SynEdit would be recognized as part of Lazarus (yes its the fpc list, but the name may still be known). So I simply gave a file location in the Lazarus source. It can be found here: https://github.com/User4martin/lazarus/blob/master/components/synedit/syneditmiscclasses.pp#L1674 Some of the code is specific to SynEdit (E.g. information on code-folding). But ReadFromClipboard https://github.com/User4martin/lazarus/blob/master/components/synedit/syneditmiscclasses.pp#L1699 checks for either flag being present, and that is all you need. => Then the normal text, and line-ends in the text mark where each column ends. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
Thanks for the info on SynEdit. Where can I find the synedit source related to the clipboard? I think the link you indtended ater 'See the code at.' Didn't come though, can you pleaese send it again? James -Original Message- From: fpc-pascal On Behalf Of Martin Frb via fpc-pascal Sent: Wednesday, December 30, 2020 7:51 PM To: James Richters via fpc-pascal Cc: Martin Frb Subject: Re: [fpc-pascal] GetClipboardFormatName causing an Error 216 On 31/12/2020 01:09, James Richters via fpc-pascal wrote: > I'm trying to write a programs to get data from the windows clipboard > that was put into it with Notepad++ using vertical editing. > Just for Info, SynEdit (trunk) can handle notepad++ column selection See the code at. There are 2 common formats (and as a 3rd the one used by SynEdit). NP++ uses one of them, not sure which. components\synedit\syneditmiscclasses.pp TSynClipboardStream = class class function ClipboardFormatMSDEVColumnSelect: TClipboardFormat; class function ClipboardFormatBorlandIDEBlockType: TClipboardFormat; IIRC in both cases the text is in the normal ClipBoard.AsText. Each line is one column segment. 'MSDEVColumnSelect' acts as a flag if present. 'Borland IDE Block Type' has a single byte. the value $02 indicates column mode. Register the format, to get the ID, then check if it is on the clipboard. Either check the synEdit source, or google the 2 format names ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
Thank you for the help. I always seem to have difficulties understanding how to interface with windows functions. I did see the msdn help.. to me it seemed that lpszFormatName was the LPTSTR variable that would contain the name, but that's not what is being passed to it at all... it's a POINTER to the variable, the docs never said it was a pointer. This is what it shows and how I understood it: int GetClipboardFormatNameA( UINT format, // an Unsigned Integer Variable LPSTR lpszFormatName,// an LPSTR Variable which I understand is just a PChar int cchMaxCount // an Integer Variable ); There is just nothing anywhere that indicated to me that lpszFormatName was a pointer to a variable. If they were expecting a pointer, then I would think it would be shown something like this: int GetClipboardFormatNameA( UINT format, Pointer to lpszFormatName, int cchMaxCount ); Anyway, THANKS for straightening me out on this! I have it mostly working but when I try to use Move() I end up missing the first character of the format name. I assume you mentioned using UniqueString() to fix this, but I don't know how to apply it. Here is what I have now: Var FN : Array[0..255] of Byte; Format_Name, Format_Name_Move : String; ... Name_Length:=GetClipboardFormatName(Format_Id,LPTSTR(@FN[0]),255); If Name_Length >0 Then Begin Format_Name:=''; For k:= 0 to Name_Length-1 Do Format_Name:=Format_Name+Chr(FN[k]); Move(FN,Format_Name_Move,Name_Length); End; Writeln(Format_ID,'|',Name_Length,'|',Format_Name,'|',Format_Name_Move); ... Here is the Output, you can see that my loop gets the entire name, but the Move() is missing the first letter.. I:\Programming\Gcode\Test>"Clipboard Formats.exe" Number of formats: 6 13 CF_UNICODETEXT 49963|17|MSDEVColumnSelect|SDEVColumnSelect 49964|22|Borland IDE Block Type|orland IDE Block Type 16 CF_LOCALE 1 CF_TEXT 7 CF_OEMTEXT James -Original Message- From: fpc-pascal On Behalf Of Martin Frb via fpc-pascal Sent: Wednesday, December 30, 2020 8:00 PM To: fpc-pascal@lists.freepascal.org Cc: Martin Frb Subject: Re: [fpc-pascal] GetClipboardFormatName causing an Error 216 On 31/12/2020 01:09, James Richters via fpc-pascal wrote: > Var > FN : LPTSTR; > > Begin > > FN:=''; > Writeln(Format_ID); > GetClipboardFormatName(Format_Id,FN,250); > Check the msdn help. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboardformatnamea FN must point to an existing buffer (allocated mem) that receives the result. FN : Array [0..255]of Byte; GotLen := GetClipboardFormatName(Format_Id, LPTSTR(@FN[0]),250); then "move()" the received bytes into a string, make sure to use UniqueString() or similar ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
The memory for FN is allocated at the top with StrAlloc() -- Alexander Grotewohl https://dcclost.com From: fpc-pascal on behalf of Martin Frb via fpc-pascal Sent: Wednesday, December 30, 2020 8:00 PM To: fpc-pascal@lists.freepascal.org Cc: Martin Frb Subject: Re: [fpc-pascal] GetClipboardFormatName causing an Error 216 On 31/12/2020 01:09, James Richters via fpc-pascal wrote: > Var > FN : LPTSTR; > > Begin > > FN:=''; > Writeln(Format_ID); > GetClipboardFormatName(Format_Id,FN,250); > Check the msdn help. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboardformatnamea FN must point to an existing buffer (allocated mem) that receives the result. FN : Array [0..255]of Byte; GotLen := GetClipboardFormatName(Format_Id, LPTSTR(@FN[0]),250); then "move()" the received bytes into a string, make sure to use UniqueString() or similar ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
I missed you have FN:=StrAlloc (255); in that case see Alexanders response. On 31/12/2020 02:00, Martin Frb via fpc-pascal wrote: FN must point to an existing buffer (allocated mem) that receives the result. FN : Array [0..255]of Byte; GotLen := GetClipboardFormatName(Format_Id, LPTSTR(@FN[0]),250); then "move()" the received bytes into a string, make sure to use UniqueString() or similar ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
On 31/12/2020 01:09, James Richters via fpc-pascal wrote: Var FN : LPTSTR; Begin FN:=''; Writeln(Format_ID); GetClipboardFormatName(Format_Id,FN,250); Check the msdn help. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getclipboardformatnamea FN must point to an existing buffer (allocated mem) that receives the result. FN : Array [0..255]of Byte; GotLen := GetClipboardFormatName(Format_Id, LPTSTR(@FN[0]),250); then "move()" the received bytes into a string, make sure to use UniqueString() or similar ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
On 31/12/2020 01:09, James Richters via fpc-pascal wrote: I'm trying to write a programs to get data from the windows clipboard that was put into it with Notepad++ using vertical editing. Just for Info, SynEdit (trunk) can handle notepad++ column selection See the code at. There are 2 common formats (and as a 3rd the one used by SynEdit). NP++ uses one of them, not sure which. components\synedit\syneditmiscclasses.pp TSynClipboardStream = class class function ClipboardFormatMSDEVColumnSelect: TClipboardFormat; class function ClipboardFormatBorlandIDEBlockType: TClipboardFormat; IIRC in both cases the text is in the normal ClipBoard.AsText. Each line is one column segment. 'MSDEVColumnSelect' acts as a flag if present. 'Borland IDE Block Type' has a single byte. the value $02 indicates column mode. Register the format, to get the ID, then check if it is on the clipboard. Either check the synEdit source, or google the 2 format names ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] GetClipboardFormatName causing an Error 216
Your FN:=''; is clobbering the pointer 'FN' with nonsense. Just leave that line out, it isn't necessary. Or do like FN^:=#0; if you want C-string like functions to report zero length.. -- Alexander Grotewohl https://dcclost.com From: fpc-pascal on behalf of James Richters via fpc-pascal Sent: Wednesday, December 30, 2020 7:09 PM To: 'FPC-Pascal users discussions' Cc: James Richters Subject: [fpc-pascal] GetClipboardFormatName causing an Error 216 I'm trying to write a programs to get data from the windows clipboard that was put into it with Notepad++ using vertical editing. It uses a non-standard format and I'm trying to figure it out. GetClipboardFormatName is supposed to get me the name of non-standard formats, but whenever I try to run it, I get a runtime error 216 I found some python code at: https://gist.github.com/adam-p/2514182 that I'm trying to convert to FPC. My fork is at: https://gist.github.com/Zaaphod/7d94e1d712a5b9ac2bcb0bc79f039a63 Which shows both the original python code and my FPC attempt It works fine for standard formats: Running "i:\programming\gcode\test\clipboard formats.exe " Number of formats: 4 13 CF_UNICODETEXT 16 CF_LOCALE 1 CF_TEXT 7 CF_OEMTEXT But if I highlight some text in Notepadd++ using vertical editing, holding down Shift and ALT while using the arrow keys to highlight a block of text, and the copy that to the clipboard, I get the following: Running "i:\programming\gcode\test\clipboard formats.exe " Number of formats: 6 13 CF_UNICODETEXT 49882 Runtime error 216 at $774C246C $774C246C $76932F63 $76932EB7 $004017EC main, line 60 of i:/programming/gcode/test/clipboard formats.pas $00408F67 Line 60 is: GetClipboardFormatName(Format_Id,FN,250); It only gets run for non-standard formats. As I understand it that's all it us supposed to be used for. It's pretty short program so I pasted it below. Any ideas on what I'm doing wrong here? James - uses Windows,strings; Type BT = Record BT_ID: Byte; BT_Name: String; End; Const builtin_type: Array [0..22] of BT = ( { 0} (BT_ID:2 ;BT_Name:'CF_BITMAP' ), { 1} (BT_ID:8 ;BT_Name:'CF_DIB'), { 2} (BT_ID:17 ;BT_Name:'CF_DIBV5' ), { 3} (BT_ID:5 ;BT_Name:'CF_DIF'), { 4} (BT_ID:130 ;BT_Name:'CF_DSPBITMAP' ), { 5} (BT_ID:142 ;BT_Name:'CF_DSPENHMETAFILE' ), { 6} (BT_ID:131 ;BT_Name:'CF_DSPMETAFILEPICT'), { 7} (BT_ID:129 ;BT_Name:'CF_DSPTEXT'), { 8} (BT_ID:14 ;BT_Name:'CF_ENHMETAFILE'), { 9} (BT_ID:15 ;BT_Name:'CF_HDROP' ), {10} (BT_ID:16 ;BT_Name:'CF_LOCALE' ), {11} (BT_ID:18 ;BT_Name:'CF_MAX'), {12} (BT_ID:3 ;BT_Name:'CF_METAFILEPICT' ), {13} (BT_ID:7 ;BT_Name:'CF_OEMTEXT'), {14} (BT_ID:128 ;BT_Name:'CF_OWNERDISPLAY' ), {15} (BT_ID:9 ;BT_Name:'CF_PALETTE'), {16} (BT_ID:10 ;BT_Name:'CF_PENDATA'), {17} (BT_ID:11 ;BT_Name:'CF_RIFF' ), {18} (BT_ID:4 ;BT_Name:'CF_SYLK' ), {19} (BT_ID:1 ;BT_Name:'CF_TEXT' ), {20} (BT_ID:6 ;BT_Name:'CF_TIFF' ), {21} (BT_ID:13 ;BT_Name:'CF_UNICODETEXT'), {22} (BT_ID:12 ;BT_Name:'CF_WAVE' )); Var i,j,Number_Of_Formats : Byte; Format_ID : DWord; FN : LPTSTR; Format_Name : String; Begin FN:=StrAlloc (255); OpenClipboard(0); Number_Of_Formats := CountClipboardFormats(); Writeln('Number of formats: ',Number_Of_Formats); format_id := 0; for i := 1 to Number_Of_Formats do Begin Format_Name := 'FAILED'; Format_ID:=EnumClipboardFormats(Format_ID); For J:= 0 to 22 do Begin If Format_ID = builtin_type[J].BT_ID then Format_Name := builtin_type[J].BT_Name; End; If Format_Name = 'FAILED' Then Begin FN:=''; Writeln(Format_ID); GetClipboardFormatName(Format_Id,FN,250); Writeln(FN); If strpas(FN) <> '' Then Format_Name := StrPas(FN); End; Writeln(Format_ID,' ',Format_Name); End; CloseClipboard(); End. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal