4.4.6 Registering an Initial Document (optional)

For all cases other than where /Embedding (or -Embedding) only was on the command line, the server application needs to call OleRegisterServerDoc to inform the server DLL that this instance of the server has an open document. A server application should never call OleRegisterServerDoc when it starts to edit an embedded object because the server DLL has already registered the document.

If the command line contains a filename with or without /Embedding, then there is a document name to pass to OleRegisterServerDoc; otherwise, use a string like "(Untitled)" to register a new, unnamed document. If OleRegisterServerDoc returns OLE_OK, then continue initialization. Otherwise, the server should call OleRevokeServer and fail the initialization because it cannot implement OLE without a document. (OleRevokeServer will always return OLE_OK here because there has not yet been any conversations initiated.)

In SRVRDEMO.EXE, if ProcessCmdLine determines that a new document needs to be created and registered, it calls CreateUntitledDoc, which creates and registers a new document and object by calling CreateNewDoc and CreateNewObj, respectively.

The following code examples show the sequence of creating and registering a new OLE document, once CreateUntitledDoc is called from ProcessCmdLine:

static BOOL CreateUntitledDoc (int nCmdShow)

{

if (!CreateNewDoc (NULL, "(Untitled)", doctypeNew))

return FALSE;

CreateNewObj (FALSE);

ShowWindow(hwndMain, nCmdShow);

UpdateWindow(hwndMain);

return TRUE;

}

/* CreateNewDoc */

BOOL CreateNewDoc (LONG lhdoc, LPSTR lpszDoc,

DOCTYPE doctype)

{

int i;

// Fill in the fields of the document structure.

if (lhdoc == NULL)

{

if (OLE_OK != OleRegisterServerDoc (srvrMain.lhsrvr,

lpszDoc, LPOLESERVERDOC) &docMain,

(LHSERVERDOC FAR *) &docMain.lhdoc))

return FALSE;

}

else

docMain.lhdoc = lhdoc;

docMain.doctype = doctype;

docMain.oledoc.lpvtbl= &docvtbl;

//Reset all flags since no object numbers have been used

for (i=1; i <= cfObjNums; i++)

docMain.rgfObjNums[i] = FALSE;

fDocChanged = FALSE;

SetTitle (lpszDoc, doctype == doctypeEmbedded);

return TRUE;

}

/* CreateNewObj

*

* BOOL fDoc_Changed - The new value for the global variable

* fDocChanged. When initializing a new

* document, we need to create a new

* object without the creation counting

* as a change to the document.

*

* RETURNS: A pointer to the new object

*/

LPOBJ CreateNewObj (BOOL fDoc_Changed)

{

HANDLE hObj = NULL;

LPOBJ lpobj = NULL;

// index into an array of flags indicating if that

// object number is used.

int ifObj = 0;

if ((hObj = LocalAlloc (LMEM_MOVEABLE|LMEM_ZEROINIT,

sizeof (OBJ))) == NULL)

return NULL;

if ((lpobj = (LPOBJ) LocalLock (hObj)) == NULL)

{

LocalFree (hObj);

return NULL;

}

// Fill the fields in the object structure.

// Find an unused number.

for (ifObj=1; ifObj <= cfObjNums; ifObj++)

{

if (docMain.rgfObjNums[ifObj]==FALSE)

{

docMain.rgfObjNums[ifObj]=TRUE;

break;

}

}

if (ifObj==cfObjNums+1)

{

// Cannot create any more objects.

MessageBeep(0);

return NULL;

}

wsprintf (lpobj->native.szName, "Object %d", ifObj);

lpobj->aName = GlobalAddAtom (lpobj->native.szName);

lpobj->hObj = hObj;

lpobj->oleobject.lpvtbl = &objvtbl;

lpobj->native.idmColor = IDM_RED; // Default color

lpobj->native.version = version;

lpobj->native.nWidth = OBJECT_WIDTH; // Default size

lpobj->native.nHeight = OBJECT_HEIGHT;

SetHiMetricFields (lpobj);

// Place object in a location corresponding to its

// number, for aesthetics.

lpobj->native.nX = (ifObj - 1) * 20;

lpobj->native.nY = (ifObj - 1) * 20;

if (!CreateWindow ("ObjClass", "Obj", WS_BORDER |

WS_THICKFRAME | WS_CHILD | WS_CLIPSIBLINGS |

WS_VISIBLE, lpobj->native.nX, lpobj->native.nY,

lpobj->native.nWidth, lpobj->native.nHeight,

hwndMain, NULL, hInst, (LPSTR) lpobj ))

return FALSE;

fDocChanged = fDoc_Changed;

return lpobj;

}