Hi, All
Could you tell me what is the standard object-oriented way to re-design a pointer-based memory allocation solution so as not to have to calculate explicitly how much memory is required for a given data type but that a memory manager determines whether the allocation is possible at a given run-time?
If this problem sounds just shy of tracktable as stated, I can provide source code fragment.
Thanks in advance,
Paule
----- Original Message ----- From: "Rob Kennedy" <[EMAIL PROTECTED]>
To: "Borland's Delphi Discussion List" <[email protected]>
Sent: Tuesday, April 12, 2005 1:47 PM
Subject: Re: Oh boy...need pointer help...addendum!
Robert Meek wrote:Yes I asked the wrong question! What I meant to ask was as I
obviously have to place things back on the clipboard that are in a specially
registered format, how do I do that not knowing what the format is?
But you *do* know the format. You had to know the format in order to get the data off the clipboard in the first place. When you store the data to a file, also store the name of the format.
I
haven't found anyway to use the numeric constants for these special
types...it seems you need to know the CF_ constant type? And there is no
listing I can find to use for converting from one to the other! Also, how
can I save what is on the clipboard to a stream so it can be loaded into a
blob along with it's format type so I can then load it back into the
clipboard later? There's nothing in the Clipbrd unit that I can use for
that.
If I wanted to save the contents of the clipboard in all available formats to a single file, this is the code I would use:
function GetFormatName(const Format: UInt): WideString; var Len: Integer; begin if Format < $c000 then begin Result := SysUtils.Format('#%u', [Format]); end else begin Len := 400; SetLength(Result, Len); Len := GetClipboardFormatNameW(Format, PWideChar(Result), Len); Win32Check(Len <> 0); SetLength(Result, Len); end; end;
procedure SaveClipboardToFile(const FileName: WideString);
var
OutHandle: THandle;
OutFile: TStream;
Format: DWord;
FormatName: WideString;
NameLen: LongWord;
Data: THandle;
DataBuffer: Pointer;
DataSize: LongWord;
begin
Win32Check(OpenClipboard(0));
try
OutHandle := CreateFileW(PWideChar(FileName), Generic_Write, 0, nil, Create_Always, File_Attribute_Archive or File_Flag_Sequential_Scan, 0);
Win32Check(OutHandle <> Invalid_Handle_Value);
try
OutFile := THandleStream.Create(Integer(OutHandle));
try
Format := EnumClipboardFormats(0);
while Format <> 0 do try
FormatName := GetFormatName(Format);
NameLen := Length(FormatName);
if NameLen = 0 then continue;
OutFile.Write(NameLen, SizeOf(NameLen));
if NameLen > 0 then OutFile.Write(FormatName[1], NameLen * SizeOf(FormatName[1]));
Data := GetClipboardData(Format); Win32Check(Data <> 0);
DataBuffer := GlobalLock(Data); try DataSize := GlobalSize(Data); OutFile.Write(DataSize, SizeOf(DataSize)); OutFile.Write(DataBuffer^, DataSize); finally GlobalUnlock(Data); end; finally Format := EnumClipboardFormats(Format); end; Assert(Format = 0); if GetLastError <> Error_Success then RaiseLastOSError; // Use 0 to designate end of data OutFile.Write(Format, SizeOf(Format)); finally OutFile.Free; end; finally CloseHandle(OutHandle); end; finally CloseClipboard; end; end;
It's naive. It doesn't account for private clipboard formats, and it also doesn't make any effort to detect and skip synthesized clipboard formats.
The procedure saves the clipboard data in a list. First it writes the name of the format, and then it writes the data. Both the name and the data get prefixed by their lengths first so that they can be read back correctly later. Below is a procedure that should be able to read the data and put it back on the clipboard.
function GetFormatNumber(const Name: WideString): UInt; begin if Name[1] = '#' then begin Result := StrToInt(Copy(Name, 2, MaxInt)); end else begin Result := RegisterClipboardFormatW(PWideChar(Name)); end; end;
procedure LoadClipboardFromFile(const FileName: WideString);
var
InHandle: THandle;
InFile: TStream;
Format: DWord;
FormatName: WideString;
NameLen: LongWord;
Data: THandle;
DataBuffer: Pointer;
DataSize: LongWord;
begin
Win32Check(OpenClipboard(0));
try
Win32Check(EmptyClipboard);
InHandle := CreateFileW(PWideChar(FileName), Generic_Read, 0, nil, Open_Existing, File_Attribute_Archive or File_Flag_Sequential_Scan, 0);
Win32Check(InHandle <> Invalid_Handle_Value);
try
InFile := THandleStream.Create(Integer(InHandle));
try
InFile.ReadBuffer(NameLen, SizeOf(NameLen));
while NameLen <> 0 do begin
SetLength(FormatName, NameLen);
InFile.ReadBuffer(FormatName[1], NameLen * SizeOf(FormatName[1]));
Format := GetFormatNumber(FormatName);
InFile.ReadBuffer(DataSize, SizeOf(DataSize)); Data := GlobalAlloc(GMem_Moveable or GMem_DDEShare, DataSize); Win32Check(Data <> 0); try DataBuffer := GlobalLock(Data); Win32Check(Assigned(DataBuffer)); try InFile.ReadBuffer(DataBuffer^, DataSize); SetClipboardData(Format, Data); finally GlobalUnlock(Data); end; except GlobalFree(Data); raise; end;
InFile.ReadBuffer(NameLen, SizeOf(NameLen)); end; finally InFile.Free; end; finally CloseHandle(InHandle); end; finally CloseClipboard; end; end;
I use a special format for clipboard format names because the documentat for GetClipboardFormatName suggests that the built-in formats don't have names.
-- Rob
_______________________________________________ Delphi mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi
_______________________________________________ Delphi mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi

