PERSERVE - IPersistStream Persistent Object Server SUMMARY ======= The PERSERVE sample introduces the COPageList COM object, which encapsulates a page list. The list contains elements that correspond to pages of text or drawing data. COPageList objects expose a set of interfaces that make the objects connectable, persistent managers of the list data. Client access to this data is available through an IPageList custom interface. COPageList implements the IPageList interface. A clear architectural distinction is kept between client and server. COPageList provides no graphical user interface (GUI). Instead, the COPageList object relies on the client for all GUI behavior. The PERCLIEN client provides the GUI display and manages the list of pages the content of which are stored in a compound file that contains both the contents of the list and of each page in that list. The user of PERCLIEN can edit the content of two type of pages: Text pages and drawing pages. Text pages have text data that the user can edit using a simple windowed text editor. Drawing pages have drawing data that the user can edit using free-form, scribble-like functionality based on the earlier STOSERVE and STOCLIEN samples. Both types of editing are done in separate client windows. The details of the client are covered in the PERCLIEN sample. For more information, see PERCLIEN.HTM. Storage in the compound file is achieved because the components provide persistent COM objects that encapsulate the page list and edited page data. PERSERVE houses a persistent object that encapsulates the single page list kept in each compound file containing such pages. PERTEXT houses a persistent object that encapsulates the edited text data for each text page. PERDRAW houses a persistent object that encapsulates the drawing data for each drawing page. The COPageList object in the this PERSERVE sample encapsulates the persistent page list data. COPageList implements the IPersistStream standard interface to expose control of the page list storage located in the client-provided stream of a compound file. The COTextPage object in the PERTEXT sample encapsulates the data of an edited text page. COTextPage implements the IPersistStreamInit standard interface to expose control of the text data storage that is located in the client-provided stream of a compound file. In contrast to these stream-based persistent objects, the CODrawPage object in the PERDRAW sample encapsulates the persistent drawing-ink data. CODrawPage implements the IPersistStorage standard interface to expose control of the drawing's ink data storage located in the client-provided substorage of a compound file. This code sample focuses primarily on COPageList's implementation of the IPersistStream interface to provide stream-based persistence for a COM object. PERSERVE works with the PERCLIEN code sample to illustrate the joint use by client and server of this IPersistStream-based persistence. COPageList's support for object persistence is the primary means of storing the page list data. COPageList stores its list data in a stream under the root storage of a structured-storage compound file. The compound file has a unique format because of the various streams and storages used. The client identifies these compound files as page files with a .PAG extension. Only one page-list stream is present in each page file. The client controls the use of the containing compound file and provides COPageList with an IStream pointer for its use in loading and saving its list data in the compound file. The IStream pointer is passed to COPageList in method calls to the IPersistStream interface. COPageList also exposes an IPageList custom interface to manipulate the encapsulated list data. IPageList exposes the Get, Set, Add, Delete, and Clear methods. Connectable object features are also supported in COPageList. The IConnectionPointContainer interface is exposed, and an appropriate connection point is implemented. In this context, an outgoing custom IPageListSink interface is declared to send notifications to the client. The two IPageList and IPageListSink custom interfaces are declared in IPAGES.H located in the common INC directory. PAGEGUID.H, which contains the GUIDs for the interfaces and objects, is located in that same directory. The PERSERVE sample uses the CThreaded facility in APPUTIL to achieve thread safety in the server housing and the class factory. Because PERSERVE.DLL is generally accessed from a Single Threaded Apartment (STA) as an in-process server, COPageList instances are not coded as thread-safe. The CLSID_PageList component is registered as supporting the apartment threading model. For functional descriptions and a tutorial code tour of PERSERVE, see the Code Tour section in PERSERVE.HTM. For details on setting up the programmatic usage of PERSERVE.DLL, see the Usage section in PERSERVE.HTM. To read PERSERVE.HTM, run TUTORIAL.EXE in the main tutorial directory and click the PERSERVE lesson in the table of lessons. You can also do the same thing by double-clicking the PERSERVE.HTM file after locating the main tutorial directory in Windows Explorer. See also PERCLIEN.HTM in the main tutorial directory for more details on the PERCLIEN client application and how it works with PERSERVE.DLL. You must build PERSERVE.DLL before running the PERCLIEN sample. The PERSERVE server provides a PageList component that can create instances of the COPageList COM object. COPageList is housed in the PERSERVE.DLL in-process server and is made publicly available as a custom COM component. Like all other servers in this tutorial series, PERSERVE.DLL is a self-registering COM server. It makes the COPageList object type available to clients as the PageList component in the PERSERVE server using a CLSID_PageList registration in the Registry. PERSERVE's makefile automatically registers its PageList COM component in the registry, which it must do before clients can use PERSERVE.DLL as a server for the PageList component. This self-registration is started in the makefile using the REGISTER.EXE utility built in the REGISTER sample. To build or run PERSERVE.DLL, you must build the REGISTER code sample first. For details on setting up your system to build and test the code samples in this COM Tutorial series, see TUTORIAL.HTM. The supplied MAKEFILE is Microsoft NMAKE-compatible. To create a debug build, issue the NMAKE command in the Command Prompt window. Usage ----- To use PERSERVE, a client program does not need to include PERSERVE.H or link to PERSERVE.LIB. A COM client of PERSERVE obtains access solely through COM services and the PageList object's CLSID. For PERSERVE, that CLSID is CLSID_PageList (defined in file PAGEGUID.H in the INC sibling directory). For more information about how the client obtains this access, see the PERCLIEN code sample. PERSERVE.DLL is intended primarily as a COM server. Although it can be implicitly loaded by linking to its associated .LIB file, it is normally used after an explicit LoadLibrary call, usually from within the CoGetClassObject function. PERSERVE is a self-registering in-process server. The makefile that builds this sample automatically registers the server in the registry. You can manually initiate its self-registration by issuing the following command at the command prompt in the PERSERVE directory: nmake register This assumes that you have a compilation environment set up. If not, you can also directly invoke the REGISTER.EXE command at the command prompt while in the PERSERVE directory. ..\register\register.exe perserve.dll These registration commands require a prior build of both the REGISTER sample and PERSERVE.DLL. In this series, the makefiles use the REGISTER.EXE utility from the REGISTER sample. Recent releases of the Microsoft Platform SDK and Visual C++ include a utility, REGSVR32.EXE, which you can use in a similar fashion to register in-process servers and marshaling DLLs. FILES ===== Files Description PERSERVE.TXT This file. MAKEFILE The generic makefile for building the PERSERVE.DLL code sample of this lesson. PERSERVE.H The include file for declaring as imported or defining as exported the service functions in PERSERVE.DLL. PERSERVE.CPP The main implementation file for PERSERVE.DLL. Has DllMain and the COM server functions (for example, DllGetClassObject). PERSERVE.DEF The module definition file. Exports server housing functions. PERSERVE.RC The DLL resource definition file for the executable. PERSERVE.ICO The icon resource for the executable. SERVER.H The include file for the server control C++ object. SERVER.CPP The implementation file for the server control C++ object. FACTORY.H The include file for the server's class factory COM objects. FACTORY.CPP The implementation file for the server's class factories. CONNECT.H The include file for the connection point enumerator, connection point, and connection enumerator classes. CONNECT.CPP The implementation file for the connection point enumerator, connection point, and connection enumerators objects. PAGELIST.H The include file for the COPageList COM object class. PAGELIST.CPP The implementation file for the COPageList COM object class and the connection points.