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