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 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.
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.
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.
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;
}
|
|