|
Serialization is the process of storing all the objects data in an
efficient binary format. The ProEssentials API includes a variety of functions
to implement serialization.
.NET Related Function
ActiveX and SDK/DLL Functions
The developer can utilize these functions
to add chart persistence to their applications.
PEsavetofile and PEloadfromfile
store and retrieve data from a file. Care must be taken to make sure that
the correct object type (Graph, Scientific Graph, 3D Scientific Graph,
Polar Object or Pie Chart Object) is used with PEloadfromfile
as was used with PEsavetofile.
Generally you will name files in a method which identifies which type
of object is stored.
PEstore and PEload
store and retrieve data from a global memory object. The Windows API function
GlobalAlloc creates a global memory
object. GlobalLock gives you a
pointer to the data.
PEstorepartial and PEloadpartial
function much the same way as PEstore
and PEload except that they exclude
the large data properties such as YData
and XData. This is useful if you want
to store the chart's characteristics without saving the chart's data.
The developer can use these functions to save an objects data to a
file or into a Memo field of a database record. Another feature that could
be implemented is an undo feature. Maintain the returned global handle
from PEstore as long as the application
is active. No need to deference it with GlobalLock,
but use the handle with PEload
in order to undo changes the user may have made.
Examples of using PEstore and PEload
Within .NET, these function are generally not needed as SaveObjectToStream provides similar functionality.
The following is example code which stores and reloads an objects data
via serialization to a file. PEstorepartial and PEloadpartial work in an identical fashion. You can use this information
if you need more control than what PEsavetofile and PEloadfromfile provides. Examples
are in C, VB, Delphi, and Builder.
C / C++ Example
The handle hWndPE points to a global variable specifying an object previously
created.
|
void FAR* lpdata;
DWORD dwWritten;
OFSTRUCT MyOF;
HFILE hFile;
HGLOBAL hGlobal = 0;
DWORD dwSize = 0;
/* to store the data */
if (!PEstore (hWndPE, &hGlobal, &dwSize))
{ /* error handler */ }
/* hGlobal now contains a valid handle
and dwSize specifies the size stored.
Use GlobalLock to get a pointer to data
and then call GlobalUnlock when finished
with the pointer. */
lpdata = GlobalLock(hGlobal);
/* open file */
hFile = OpenFile("Test.dat", &MyOF, OF_CREATE|OF_READWRITE);
/* save size so we know how much to allocate later when loading */
dwWritten = hwrite(hFile, dwSize, 4);
/* save actual data */
dwWritten = hwrite(hFile, lpdata, dwSize);
lclose(hFile);
GlobalUnlock(hGlobal);
GlobalFree(hGlobal);
/* to later retrieve the data */
HGLOBAL hGlobal;
DWORD dwSize;
void FAR* lpdata;
DWORD dwRead;
OFSTRUCT MyOF;
HFILE hFile;
/* open file */
hFile = OpenFile("Test.dat", &MyOF, OF_READ);
/* read size to allocate correct amount */
dwRead = hread(hFile, dwSize, 4)
/* allocate memory */
hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwSize);
lpdata = GlobalLock(hGlobal);
/* read in actual data */
dwRead = hread(hFile, ByVal lpdata, dwSize);
GlobalUnlock(hGlobal);
lclose(hFile);
/* load data from global memory object */
PEload(hWndPE, hGlobal);
GlobalFree(hGlobal);
/* reinitialize to newly loaded data */
PEreinitialize (hWndPE);
PEresetimage (hWndPE, 0, 0); |
Visual Basic 6 Example
The PEstore function creates
a global handle and Visual Basic has no simple means to deference the
handle to manipulate the binary data. However, you can use these functions
to store and load data to disk. Once in a file you could manipulate the
binary data.
The following example shows how you can call the PEstore
and PEload serialization functions
in Visual Basic to save and load the object from a file. For complete
example code (including necessary declarations) see "SAVELOAD.TXT"
in the ProEssentials TechNote directory.
PEGraph1 is a 32 bit OCX Graph Object placed into a form.
|
' to store data
Dim hGlobal As Long
Dim lpdata As Long
Dim dwSize As Long
Dim dwWritten As Long
Dim MyOF As OFstruct
Dim hFile As Long
Dim test As Long
hGlobal = 0
dwSize = 0
test = PEstore(PEGraph1, hGlobal, dwSize)
lpdata = GlobalLock(hGlobal)
'4098=CREATE+READWRITE, 0=READ, 1=WRITE
hFile = OpenFile("Test.dat", MyOF, 4098)
'save size so we know how much to allocate later
dwWritten = hwrite(hFile, dwSize, 4)
'save actual data
dwWritten = hwrite(hFile, ByVal lpdata, dwSize)
test = lclose(hFile)
test = GlobalFree(hGlobal)
' to later retrieve the data
Dim hGlobal As Long
Dim lpdata As Long
Dim dwSize As Long
Dim dwRead As Long
Dim MyOF As OFstruct
Dim hFile As Long
Dim test As Long
'open file, 0=READ, 1=WRITE, 2=READWRITE
hFile = OpenFile("Test.dat", MyOF, 0) '0=READ, 1=WRITE, 2=READWRITE
'read size to allocate correct amount
dwRead = hread(hFile, dwSize, 4) 'get size to allocate
'allocate memory
hGlobal = GlobalAlloc(2, dwSize)
lpdata = GlobalLock(hGlobal)
'read in actual data
dwRead = hread(hFile, ByVal lpdata, dwSize)
test = GlobalUnlock(hGlobal)
test = lclose(hFile)
'load data from global memory object
test = PEload(PEGraph1, hGlobal)
test = GlobalFree(hGlobal)
'reinitialize to newly loaded data
PEGraph1.PEactions = 0 'reinitialize after PEload |
Delphi Example
The following example shows how you can call the PEstore
and PEload serialization functions
in Delphi to save and load the object from a file. For complete example
code (including necessary declarations) see "SAVELOAD.TXT" in
the ProEssentials TechNote directory.
PEGraph1 is a VCL Graph Object placed into a form.
|
{-----------------------------------------------------
DECLARATIONS NEEDED
Add Pegrpapi unit to your uses clause. This unit holds declarations.
FUNCTION TO SAVE OBJECT TO DISK
------------------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
hGlobal: Longint;
lpdata: Pointer;
dwSize: Longint;
dwWritten: Longint;
MyOF: TOFStruct;
hFile: Longint;
begin
hGlobal := 0;
dwSize := 0;
if (PEstore(PEGraph1.hObject, @hGlobal, @dwSize) <> 0) then
begin
lpdata := GlobalLock(hGlobal);
hFile := OpenFile('c:\Test.dat', MyOF, OF_CREATE+OF_READWRITE);
dwWritten := _hwrite(hFile, @dwSize, 4);
dwWritten := _hwrite(hFile, lpdata, dwSize);
_lclose(hFile);
GlobalUnlock(hGlobal);
GlobalFree(hGlobal);
end;
end;
{-------------------------------------------------------
FUNCTION TO LOAD OBJECT FROM DISK
-------------------------------------------------------}
procedure TForm1.Button2Click(Sender: TObject);
var
hGlobal: Longint;
lpdata: Pointer;
dwSize: Longint;
dwRead: Longint;
MyOF: TOFStruct;
hFile: Longint;
begin
hFile := OpenFile('c:\Test.dat', MyOF, 0);
dwRead := _lread(hFile, @dwSize, 4);
hGlobal := GlobalAlloc(GMEM_MOVEABLE, dwSize);
lpdata := GlobalLock(hGlobal);
dwRead := _lread(hFile, lpdata, dwSize);
GlobalUnlock(hGlobal);
_lclose(hFile);
PEload(PEGraph1.hObject, @hGlobal);
GlobalFree(hGlobal);
PEGraph1.PEactions := gReinitAndReset;
end; |
Builder Example
The following example shows how you can call the PEstore
and PEload serialization functions
in Builder to save and load the object from a file. For complete example
code see "SAVELOAD.TXT" in the ProEssentials Technote directory.
PESGraph1 is a VCL Graph Object placed into a form.
This examples uses both Windows file handling and TFileStream.
|
//-----------------------------------------------------------
void __fastcall TForm3::Button1Click(TObject *Sender)
{
// ** Saving to Disk ** //
HGLOBAL hGlobal;
LPVOID lpdata;
unsigned long dwSize;
unsigned long dwWritten;
OFSTRUCT MyOF;
HANDLE hFile;
hGlobal = 0;
dwSize = 0;
PEstore((HWND) PESGraph1->hObject, &hGlobal, &dwSize);
lpdata = GlobalLock(hGlobal);
TFileStream* tfs;
tfs = new TFileStream("c:\\test.dat", fmCreate);
tfs->WriteBuffer(&dwSize, 4);
tfs->WriteBuffer(lpdata, dwSize);
delete tfs;
// The following code does the same as above but without
// the use of TFileStream.
/*
// '4098=CREATE+READWRITE, 0=READ, 1=WRITE
hFile = (HANDLE) OpenFile("c:\Test.dat", &MyOF, 4098);
// 'save size so we know how much to allocate later
WriteFile(hFile, &dwSize, 4, &dwWritten, NULL);
// 'save actual data
WriteFile(hFile, lpdata, dwSize, &dwWritten, NULL);
_lclose((HFILE)hFile);
*/
GlobalFree(hGlobal);
}
//-----------------------------------------------------------
void __fastcall TForm3::Button2Click(TObject *Sender)
{
// ** Loading From Disk ** //
HGLOBAL hGlobal;
LPVOID lpdata;
unsigned long dwSize;
unsigned long dwRead;
OFSTRUCT MyOF;
HANDLE hFile;
hGlobal = 0;
dwSize = 0;
TFileStream* tfs;
tfs = new TFileStream("c:\\test.dat", fmOpenRead);
tfs->ReadBuffer(&dwSize, 4);
// ** If not using TFileStream
// ** 0=READ, 1=WRITE, 2=READWRITE
//hFile = (HANDLE) OpenFile("c:\Test.dat", &MyOF, 0);
// ** read size to allocate correct amount
//ReadFile(hFile, &dwSize, 4, &dwRead, NULL);
hGlobal = GlobalAlloc(2, dwSize);
lpdata = GlobalLock(hGlobal);
tfs->ReadBuffer(lpdata, dwSize);
// ** If not using TFileStream, read in actual data
//ReadFile(hFile, lpdata, dwSize, &dwRead, NULL);
GlobalUnlock(hGlobal);
delete tfs;
// ** If not using TFileStream
//_lclose((HFILE)hFile);
PEload((HWND) PESGraph1->hObject, &hGlobal);
GlobalFree(hGlobal);
// ** reinitialize after PEload
PESGraph1->PEactions = sgReinitAndReset;
} |
|