home *** CD-ROM | disk | FTP | other *** search
- /*
- OLE SERVER DEMO
- SrvrDemo.c
-
- This file contains the window handlers, and various initialization and
- utility functions.
-
- (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
- */
-
-
- #define SERVERONLY
- #include "Windows.h"
- #include "Ole.h"
- #include "SrvrDemo.h"
-
- /* Global variable definitions */
-
- HWND hwndMain = NULL;
-
- // Used in converting units from pixels to Himetric and vice-versa
- int giXppli = NULL; // pixels per logical inch along width
- int giYppli = NULL; // pixels per logical inch along height
-
- // Since this is a not an MDI app, there can be only one server and one doc.
- SRVR srvrMain;
- DOC docMain;
- char szClient[cchFilenameMax];
- char szClientDoc[cchFilenameMax];
-
- // Has the user made changes to the document?
- BOOL fDocChanged = FALSE;
-
- // Is this the first instance of this application currently running?
- BOOL fFirstInstance = TRUE;
-
- // This flag is used when OleRevokeServerDoc returns OLE_WAIT_FOR_RELEASE,
- // and we must wait until DocRelease is called.
- BOOL fWaitingForDocRelease = FALSE;
-
- // This flag is used when OleRevokeServer returns OLE_WAIT_FOR_RELEASE,
- // and we must wait until SrvrRelease is called.
- BOOL fWaitingForSrvrRelease = FALSE;
-
- // This flag is set to TRUE after an application has called OleBlockServer
- // and now wishes to unblock the queued messages. See WinMain.
- // Server Demo never sets fUnblock to TRUE because it never calls
- // OleBlockServer.
- BOOL fUnblock = FALSE;
-
- // Set this to FALSE if you want to guarantee that the server will not revoke
- // itself when SrvrRelease is called. This is used in the IDM_NEW case and
- // the IDM_OPEN case (in OpenDoc).
- BOOL fRevokeSrvrOnSrvrRelease = TRUE;
-
- // Version number, which is stored in the native data.
- VERSION version = 1;
-
- HBRUSH hbrColor[chbrMax];
-
- // Clipboard formats
- WORD cfObjectLink;
- WORD cfOwnerLink;
- WORD cfNative;
-
- // Method tables.
- OLESERVERDOCVTBL docvtbl;
- OLEOBJECTVTBL objvtbl;
- OLESERVERVTBL srvrvtbl;
-
- HANDLE hInst;
- HANDLE hAccelTable;
- HMENU hMainMenu = NULL;
-
- // Window dimensions saved in private profile.
- static struct
- {
- int nX;
- int nY;
- int nWidth;
- int nHeight;
- } dimsSaved, dimsCurrent;
-
-
- static enum
- {
- // Corresponds to the order of the menus in the .rc file.
- menuposFile,
- menuposEdit,
- menuposColor,
- menuposObject
- };
-
-
- // Static functions.
- static void DeleteInstance (void);
- static BOOL ExitApplication (BOOL);
- static void GetWord (LPSTR *plpszSrc, LPSTR lpszDst);
- static BOOL InitApplication( HANDLE hInstance);
- static BOOL InitInstance (HANDLE hInstance, BOOL fFirstInstance);
- static BOOL ProcessCmdLine (LPSTR lpszLine, int nCmdShow, HWND hwndMain);
- static void SaveDimensions (void);
- static void SkipBlanks (LPSTR *plpsz);
- static void UpdateObjMenus (void);
- static BOOL FailedUpdate(HWND);
-
- /* WinMain
- * -------
- *
- * Standard windows entry point
- *
- * CUSTOMIZATION: None
- *
- */
- int PASCAL WinMain
- (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- MSG msg;
-
- if (!hPrevInstance)
- {
- fFirstInstance = TRUE;
- if (!InitApplication(hInstance))
- return FALSE;
- }
- else
- fFirstInstance = FALSE;
-
- msg.wParam = FALSE;
-
- if (!InitInstance(hInstance, fFirstInstance))
- goto errRtn;
-
- if (!InitServer (hwndMain, hInstance))
- goto errRtn;
-
- if (!ProcessCmdLine (lpCmdLine, nCmdShow, hwndMain))
- {
- ExitApplication(FALSE);
- goto errRtn;
- }
-
- for (;;)
- {
- // Your application should set fUnblock to TRUE when it decides
- // to unblock.
- if (fUnblock)
- {
- BOOL fMoreMsgs = TRUE;
- while (fMoreMsgs)
- {
- OleUnblockServer (srvrMain.lhsrvr, &fMoreMsgs);
- }
- // We have taken care of all the messages in the OLE queue
- fUnblock = FALSE;
- }
-
- if (!GetMessage(&msg, NULL, NULL, NULL))
- break;
- if( !TranslateAccelerator(hwndMain, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
-
- errRtn:
- DeleteInstance ();
- return (msg.wParam);
- }
-
-
-
- /* InitApplication
- * ---------------
- *
- * Initialize the application - register the window classes
- *
- * HANDLE hInstance
- *
- * RETURNS: TRUE if classes are properly registered.
- * FALSE otherwise
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- static BOOL InitApplication( HANDLE hInstance )
- {
- WNDCLASS wc;
-
- wc.lpszClassName = "MainClass";
- wc.lpfnWndProc = MainWndProc;
- wc.style = NULL;
- wc.cbClsExtra = 4;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(hInstance, "DocIcon");
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = "MainMenu";
-
- if (!RegisterClass(&wc))
- return FALSE;
-
- wc.lpszClassName = "ObjClass";
- wc.lpfnWndProc = ObjWndProc;
- wc.hIcon = NULL;
- wc.cbWndExtra = cbWindExtra;
- wc.lpszMenuName = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_CROSS);
-
- if (!RegisterClass(&wc))
- return FALSE;
-
- return TRUE;
- }
-
-
-
- /* InitInstance
- * ------------
- *
- * Create brushes used by the program, the main window, and
- * do any other per-instance initialization.
- *
- * HANDLE hInstance
- *
- * RETURNS: TRUE if successful
- * FALSE otherwise.
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- static BOOL InitInstance (HANDLE hInstance, BOOL fFirstInstance)
- {
- long rglColor [chbrMax] =
- {
- 0x000000ff, // Red
- 0x0000ff00, // Green
- 0x00ff0000, // Blue
- 0x00ffffff, // White
- 0x00808080, // Gray
- 0x00ffff00, // Cyan
- 0x00ff00ff, // Magenta
- 0x0000ffff // Yellow
- };
-
-
- int iColor;
- HDC hDC;
-
- hInst = hInstance;
-
- // Initialize the method tables.
- InitVTbls ();
-
- // Initialize the brushes used.
- for (iColor = 0; iColor < chbrMax; iColor++)
- hbrColor[iColor] = CreateSolidBrush (rglColor[iColor]);
-
- // Register clipboard formats.
- cfObjectLink= RegisterClipboardFormat ("ObjectLink");
- cfOwnerLink = RegisterClipboardFormat ("OwnerLink");
- cfNative = RegisterClipboardFormat ("Native");
-
- hAccelTable = LoadAccelerators(hInst, "Accelerators");
- // hMainMenu = LoadMenu(hInst, "MainMenu");
-
-
- hwndMain = CreateWindow(
- "MainClass",
- szAppName,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 3*OBJECT_WIDTH, 3*OBJECT_HEIGHT,
- NULL,
- NULL,
- hInstance,
- NULL
- );
-
-
- if (!hwndMain)
- return FALSE;
-
- szClient[0] = NULL;
- lstrcpy (szClientDoc, "Client Document");
-
- // Initialize global variables with LOGPIXELSX and LOGPIXELSY
-
- hDC = GetDC (NULL); // Get the hDC of the desktop window
- giXppli = GetDeviceCaps (hDC, LOGPIXELSX);
- giYppli = GetDeviceCaps (hDC, LOGPIXELSY);
- ReleaseDC (NULL, hDC);
-
- return TRUE;
-
- }
-
-
-
- /* DeleteInstance
- * --------------
- *
- * Deallocate the VTables, and the brushes created for this instance
- *
- *
- * CUSTOMIZATION: The call to FreeVTbls must remain.
- *
- */
- static void DeleteInstance (void)
- {
- int i;
-
- // Free the method table instances.
- FreeVTbls ();
-
- for (i = 0; i < chbrMax; i++)
- DeleteObject (hbrColor[i]);
- }
-
-
-
- /* ExitApplication
- * ---------------
- *
- * Handles the WM_CLOSE and WM_COMMAND/IDM_EXIT messages.
- *
- * RETURNS: TRUE if application should really terminate
- * FALSE if not
- *
- *
- * CUSTOMIZATION: None
- *
- */
- static BOOL ExitApplication (BOOL fUpdateLater)
- {
-
- if (fUpdateLater)
- {
- // The non-standard OLE client did not accept the update
- // when we requested it, so we are sending the client
- // OLE_CLOSED now that we are closing the document.
- SendDocMsg (OLE_CLOSED);
- }
-
- if (StartRevokingServer() == OLE_WAIT_FOR_RELEASE)
- Wait (&fWaitingForSrvrRelease);
- /* SrvrRelease will not necessarily post a WM_QUIT message.
- If the document is not embedded, SrvrRelease by itself does
- not cause the application to terminate. But now we want it to.
- */
- if (docMain.doctype != doctypeEmbedded)
- PostQuitMessage(0);
- SaveDimensions();
- return TRUE;
- }
-
-
-
- /* MainWndProc
- * -----------
- *
- * Main window message handler.
- *
- *
- * CUSTOMIZATION: Remove the color menu and the object menu entirely.
- * Add handlers for your application's menu items and any
- * Windows messages your application needs to handle.
- * The handlers for the menu items that involve OLE
- * can be added to, but no logic should be removed.
- *
- *
- */
- long FAR PASCAL __export MainWndProc
- (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
- {
- LPOBJ lpobj;
-
- switch (message)
- {
- case WM_COMMAND:
-
- if (fWaitingForDocRelease)
- {
- ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
- return NULL;
- }
-
- switch (wParam)
- {
- case IDM_EXIT:
- SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
- break;
-
- case IDM_ABOUT:
- {
- FARPROC lpProcAbout = MakeProcInstance(About, hInst);
- DialogBox(hInst, "AboutBox", hwnd, lpProcAbout);
- FreeProcInstance(lpProcAbout);
- break;
- }
-
-
- case IDM_NEW:
- {
- BOOL fUpdateLater;
- OLESTATUS olestatus;
-
- if (SaveChangesOption (&fUpdateLater) == IDCANCEL)
- break;
- else if (fUpdateLater)
- SendDocMsg (OLE_CLOSED);
-
- // We want to revoke the doc but not the server, so if
- // SrvrRelease is called, do not revoke server.
- fRevokeSrvrOnSrvrRelease = FALSE;
-
- if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE)
- {
- ErrorBox ("Serious Error: Cannot revoke document.");
- break;
- }
- else if (olestatus == OLE_WAIT_FOR_RELEASE)
- Wait (&fWaitingForDocRelease);
-
- fRevokeSrvrOnSrvrRelease = TRUE;
-
- if (!CreateNewDoc (NULL, "(Untitled)", doctypeNew))
- {
- ErrorBox ("Serious Error: Cannot create new document.");
- break;
- }
- // Your application need not create a default object.
- CreateNewObj (FALSE);
- EmbeddingModeOff();
- break;
- }
- case IDM_OPEN:
- OpenDoc();
- UpdateObjMenus();
- break;
-
- case IDM_SAVE:
- SaveDoc();
- break;
-
- case IDM_SAVEAS:
- if (!SaveDocAs ())
- break;
- if (docMain.doctype != doctypeEmbedded)
- EmbeddingModeOff();
- break;
-
- case IDM_UPDATE:
- switch (OleSavedServerDoc (docMain.lhdoc))
- {
- case OLE_ERROR_CANT_UPDATE_CLIENT:
- if (!FailedUpdate(hwnd))
- ExitApplication(TRUE);
- break;
- case OLE_OK:
- break;
- default:
- ErrorBox ("Serious Error: Cannot update.");
- }
- break;
-
- /* Color menu */
-
- case IDM_RED:
- case IDM_GREEN:
- case IDM_BLUE:
- case IDM_WHITE:
- case IDM_GRAY:
- case IDM_CYAN:
- case IDM_MAGENTA:
- case IDM_YELLOW:
- lpobj = SelectedObject();
- lpobj->native.idmColor = wParam;
- // Recolor the object on the screen.
- InvalidateRect (lpobj->hwnd, (LPRECT)NULL, TRUE);
- UpdateWindow (lpobj->hwnd);
- fDocChanged = TRUE;
- if (docMain.doctype == doctypeFromFile)
- // If object is linked, update it in client now.
- SendObjMsg (lpobj, OLE_CHANGED);
- break;
-
- /* Edit menu */
-
- case IDM_COPY:
- CutOrCopyObj (TRUE);
- break;
-
- case IDM_CUT:
- CutOrCopyObj (FALSE);
- // Fall through.
-
- case IDM_DELETE:
- RevokeObj (SelectedObject());
- DestroyWindow (SelectedObjectWindow());
- UpdateObjMenus();
- break;
-
- /* Object menu */
-
- case IDM_NEXTOBJ:
- lpobj = SelectedObject();
- /* The 1 in the second parameter puts the current window
- at the bottom of the current window list. */
- SetWindowPos(lpobj->hwnd, 1, 0,0,0,0,
- SWP_NOMOVE | SWP_NOSIZE);
- break;
-
- case IDM_NEWOBJ:
- lpobj = CreateNewObj (TRUE);
- BringWindowToTop(lpobj->hwnd);
- break;
-
- default:
- ErrorBox ("Unknown Command.");
- break;
- }
- break;
-
-
- case WM_NCCALCSIZE:
- if (!IsIconic(hwnd) && !IsZoomed(hwnd))
- {
- dimsCurrent.nX = ((LPRECT)lParam)->left;
- dimsCurrent.nWidth = ((LPRECT)lParam)->right - dimsCurrent.nX;
- dimsCurrent.nY = ((LPRECT)lParam)->top;
- dimsCurrent.nHeight = ((LPRECT)lParam)->bottom - dimsCurrent.nY;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- break;
-
- case WM_QUERYENDSESSION:
- {
- BOOL fUpdateLater;
-
- if (SaveChangesOption(&fUpdateLater) == IDCANCEL)
- return FALSE;
-
- if (fUpdateLater)
- {
- // The non-standard OLE client did not accept the update
- // when we requested it, so we are sending the client
- // OLE_CLOSED now that we are closing the document.
- SendDocMsg (OLE_CLOSED);
- }
- return TRUE;
- }
-
- case WM_CLOSE:
- {
- BOOL fUpdateLater;
-
- if (SaveChangesOption(&fUpdateLater) != IDCANCEL)
- ExitApplication(fUpdateLater);
- break;
- }
-
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- return NULL;
- }
-
-
-
- /* About
- * -----
- *
- * "About Box" dialog handler.
- *
- * CUSTOMIZATION: None
- *
- */
- BOOL FAR PASCAL __export About (HWND hDlg, unsigned message, WORD wParam, LONG lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- if (wParam == IDOK || wParam == IDCANCEL)
- {
- EndDialog(hDlg, TRUE);
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-
-
-
-
- /* ObjWndProc
- * ----------
- *
- * Message handler for the object windows.
- *
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- long FAR PASCAL __export ObjWndProc
- (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static BOOL fCapture = FALSE;
- static struct {RECT rect; POINT pt;} drag;
- static RECT rectMain;
-
- switch (message)
- {
- case WM_CREATE:
- {
- LPOBJ lpobj;
- LPCREATESTRUCT lpcs;
- // The call to CreateWindow puts lpobj into lpCreateParams
- lpcs = (LPCREATESTRUCT) lParam;
- lpobj = (LPOBJ) lpcs->lpCreateParams;
- // Associate the window just created with the object.
- lpobj->hwnd = hwnd;
- /* Store pointer to object in the window structure. */
- SetWindowLong(hwnd, ibLpobj, (LONG) lpobj);
- UpdateObjMenus ();
- break;
- }
- case WM_SIZE:
- {
- RECT rect;
- if (fWaitingForDocRelease)
- {
- ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
- return NULL;
- }
- // Get coordinates of object relative to main window's client area.
- GetWindowRect (hwnd, (LPRECT)&rect);
- ScreenToClient (hwndMain, (LPPOINT)&rect);
- ScreenToClient (hwndMain, (LPPOINT)&rect.right);
- SizeObj (hwnd, rect, TRUE);
- // Fall through.
- }
- case WM_PAINT:
- PaintObj (hwnd);
- break;
-
- case WM_LBUTTONDOWN:
- if (fWaitingForDocRelease)
- {
- ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
- return NULL;
- }
- BringWindowToTop (hwnd);
-
- GetWindowRect (hwnd, (LPRECT) &drag.rect);
- ScreenToClient (hwndMain, (LPPOINT)&drag.rect.left);
- ScreenToClient (hwndMain, (LPPOINT)&drag.rect.right);
-
- drag.pt.x = LOWORD(lParam);
- drag.pt.y = HIWORD(lParam);
-
- // Convert drag.pt to the main window's client coordinates.
- ClientToScreen (hwnd, (LPPOINT)&drag.pt);
- ScreenToClient (hwndMain, (LPPOINT)&drag.pt);
-
- // Remember the coordinates of the main window so we do not drag
- // an object outside the main window.
- GetClientRect (hwndMain, (LPRECT) &rectMain);
-
- SetCapture (hwnd);
- fCapture = TRUE;
- break;
-
- case WM_MOUSEMOVE:
- {
- HDC hdc;
- POINT pt;
-
- if (!fCapture)
- break;
-
- fDocChanged = TRUE;
- pt.x = LOWORD(lParam);
- pt.y = HIWORD(lParam);
-
- // Convert pt to the main window's client coordinates.
- ClientToScreen (hwnd, (LPPOINT)&pt);
- ScreenToClient (hwndMain, (LPPOINT)&pt);
-
- if (!PtInRect (&rectMain, pt))
- break;
-
- hdc = GetDC(hwndMain);
-
- // Erase old drag rectangle
- InvertRect (hdc, (LPRECT)&drag.rect);
-
- // Update drag.rect
- OffsetRect (&drag.rect, pt.x - drag.pt.x, pt.y - drag.pt.y);
-
- // Update drag.pt
- drag.pt.x = pt.x;
- drag.pt.y = pt.y;
-
- // Show new drag rectangle
- InvertRect (hdc, (LPRECT)&drag.rect);
- ReleaseDC (hwndMain, hdc);
- break;
- }
-
- case WM_LBUTTONUP:
- {
- LPOBJ lpobj;
- if (!fCapture)
- return TRUE;
-
- fCapture = FALSE;
- ReleaseCapture ();
-
- MoveWindow (hwnd, drag.rect.left, drag.rect.top,
- drag.rect.right - drag.rect.left,
- drag.rect.bottom - drag.rect.top, TRUE);
- InvalidateRect (hwnd, (LPRECT)NULL, TRUE);
- lpobj = HwndToLpobj (hwnd);
- lpobj->native.nX = drag.rect.left;
- lpobj->native.nY = drag.rect.top;
- break;
- }
- case WM_DESTROY:
- DestroyObj (hwnd);
- return DefWindowProc(hwnd, message, wParam, lParam);
-
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- return NULL;
- }
-
-
-
- /* DeviceToHiMetric
- * ----------------
- *
- * Converts a point from device units to HiMetric units.
- * This function is designed to be generic enough to be reused.
- *
- * HWND hwnd - The window whose display context is to be used
- * LPPOINT lppt - The point to be converted.
- *
- * CUSTOMIZATION: None
- *
- */
- void DeviceToHiMetric (HWND hwnd, LPPOINT lppt)
- {
- lppt->x = MulDiv (lppt->x, HIMETRIC_PER_INCH, giXppli);
- lppt->y = MulDiv (lppt->y, HIMETRIC_PER_INCH, giYppli);
- }
-
-
- /* UpdateFileMenu
- * --------------
- *
- * Updates the "Update <Client doc>" and "Exit & Return to <Client doc>"
- * with the currently set client document name
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- void UpdateFileMenu (int iSaveUpdateId)
- {
- char str[cchFilenameMax];
- HMENU hMenu = GetMenu(hwndMain);
-
- /* Change File menu so it contains "Update" instead of "Save". */
-
- lstrcpy (str, "&Update ");
- lstrcat (str, szClientDoc);
- ModifyMenu(hMenu, iSaveUpdateId, MF_BYCOMMAND|MF_STRING, IDM_UPDATE, str);
-
- /* Change File menu so it contains "Exit & Return to <client doc>" */
- /* instead of just "Exit" */
-
- lstrcpy (str, "E&xit && Return to ");
- lstrcat (str, szClientDoc);
- ModifyMenu(hMenu, IDM_EXIT, MF_BYCOMMAND|MF_STRING, IDM_EXIT, str);
- }
-
-
-
- /* EmbeddingModeOn
- * ---------------
- *
- * Do whatever is necessary for the application to start "embedding mode."
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- void EmbeddingModeOn(void)
- {
- HMENU hMenu = GetMenu(hwndMain);
-
- UpdateFileMenu (IDM_SAVE);
-
- /* Change File menu so it contains "Save Copy As..." instead of */
- /* "Save As..." */
- ModifyMenu(hMenu, IDM_SAVEAS, MF_BYCOMMAND|MF_STRING, IDM_SAVEAS,
- "Save Copy As..");
-
- /* In embedded mode, the user can edit only the embedded object, not
- create new ones. */
- EnableMenuItem(hMenu, menuposObject, MF_BYPOSITION | MF_GRAYED);
- EnableMenuItem(hMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(hMenu, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED);
- DrawMenuBar (hwndMain);
- }
-
-
-
-
- /* EmbeddingModeOff
- * ----------------
- *
- * Do whatever is necessary for the application to end "embedding mode."
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- void EmbeddingModeOff (void)
- {
- HMENU hMenu = GetMenu(hwndMain);
-
- /* Change File menu so it contains "Save" instead of "Update". */
- ModifyMenu(hMenu, IDM_UPDATE, MF_BYCOMMAND | MF_STRING, IDM_SAVE, "&Save");
- /* Change File menu so it contains "Exit & Return to <client doc>" */
- /* instead of just "Exit" */
- ModifyMenu(hMenu, IDM_EXIT, MF_BYCOMMAND | MF_STRING, IDM_EXIT, "E&xit");
-
- /* Change File menu so it contains "Save As..." instead of */
- /* "Save Copy As..." */
- ModifyMenu(hMenu, IDM_SAVEAS, MF_BYCOMMAND|MF_STRING, IDM_SAVEAS,
- "Save As..");
-
- /* In non-embedded mode, the user can create new objects. */
- EnableMenuItem(hMenu, menuposObject, MF_BYPOSITION | MF_ENABLED);
-
- lstrcpy (szClientDoc, "Client Document");
- DrawMenuBar (hwndMain);
- }
-
-
-
- /* ErrorBox
- * --------
- *
- * char *szMessage - String to display inside message box.
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- void ErrorBox (char *szMessage)
- {
- MessageBox (hwndMain, szMessage, szAppName, MB_OK);
- }
-
-
-
- /* GetWord
- * -------
- *
- * LPSTR *plpszSrc - Pointer to a pointer to a source string
- * LPSTR lpszDst - Pointer to destination buffer
- *
- * Will copy one space-terminated or null-terminated word from the source
- * string to the destination buffer.
- * When done, *plpszSrc will point to the character after the word.
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- static void GetWord (LPSTR *plpszSrc, LPSTR lpszDst)
- {
- int i = 0;
- while (**plpszSrc && **plpszSrc != ' ')
- {
- lpszDst[i++] = *(*plpszSrc)++;
- }
- lpszDst[i] = '\0';
- }
-
-
-
- /* HiMetricToDevice
- * ----------------
- *
- * Converts a point from HiMetric units to device units.
- * This function is designed to be generic enough to be reused.
- *
- * HWND hwnd - The window whose display context is to be used
- * LPPOINT lppt - The point to be converted.
- *
- * CUSTOMIZATION: None
- *
- */
- void HiMetricToDevice (HWND hwnd, LPPOINT lppt)
- {
- lppt->x = MulDiv (giXppli, lppt->x, HIMETRIC_PER_INCH);
- lppt->y = MulDiv (giYppli, lppt->y, HIMETRIC_PER_INCH);
- }
-
-
-
- /* HwndToLpobj
- * -----------
- *
- * Given an object's window, return a pointer to the object.
- * The GetWindowLong call extracts an LPOBJ from the extra data stored with
- * the window.
- *
- * HWND hwndObj - Handle to the object's window
- *
- * RETURNS: A pointer to the object
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- LPOBJ HwndToLpobj (HWND hwndObj)
- {
- return (LPOBJ) GetWindowLong (hwndObj, ibLpobj);
- }
-
-
-
- /* CreateUntitledDoc
- * -----------------
- *
- * Create a fresh document with one object.
- *
- * RETURNS: TRUE if successful
- * FALSE otherwise
- *
- * CUSTOMIZATION: Re-implement
- *
- */
- static BOOL CreateUntitledDoc (int nCmdShow)
- {
- if (!CreateNewDoc (NULL, "(Untitled)", doctypeNew))
- return FALSE;
- CreateNewObj (FALSE);
- ShowWindow(hwndMain, nCmdShow);
- UpdateWindow(hwndMain);
- return TRUE;
- }
-
-
- /* ProcessCmdLine
- * --------------
- *
- * Parses the Windows command line which was passed to WinMain.
- *
- * Case One: SrvrDemo.exe
- * fEmbedding = FALSE
- * Create an untitled document.
- *
- * Case two: SrvrDemo.exe filename
- * fEmbedding = FALSE
- * Create a new document from the file.
- *
- * Case three: SrvrDemo.exe -Embedding
- * fEmbedding = TRUE
- * Do not create or register a document.
- * Do not show window until client requests it.
- *
- * Case four: SrvrDemo.exe -Embedding filename
- * fEmbedding = TRUE
- * Load file.
- * Call OleRegisterServerDoc.
- * Do not show window until client requests it.
- *
- *
- * LPSTR lpszLine - The Windows command line
- * int nCmdShow - Parameter to WinMain
- * HWND hwndMain - The application's main window
- *
- * RETURNS: TRUE if the command line was processed correctly.
- * FALSE if a filename was specified which did not
- * contain a proper document.
- *
- * CUSTOMIZATION: None.
- *
- */
- static BOOL ProcessCmdLine (LPSTR lpszLine, int nCmdShow, HWND hwndMain)
- {
- char szBuf[cchFilenameMax];
- BOOL fEmbedding = FALSE; // Is "-Embedding" on the command line?
- int i=0;
- OFSTRUCT of;
-
- if (!*lpszLine) // No filename or options, so start a fresh document.
- {
- return CreateUntitledDoc(nCmdShow);
- }
-
- SkipBlanks (&lpszLine);
-
- // Check for "-Embedding" or "/Embedding" and set fEmbedding.
- if(*lpszLine == '-' || *lpszLine == '/')
- {
- lpszLine++;
- GetWord (&lpszLine, szBuf);
- fEmbedding = !lstrcmp(szBuf, szEmbeddingFlag);
- }
-
- SkipBlanks (&lpszLine);
-
- if (*lpszLine) // if there is a filename
- {
- // Put filename into szBuf.
- GetWord (&lpszLine, szBuf);
-
- if (-1 == OpenFile(szBuf, &of, OF_READ | OF_EXIST))
- {
- // File not found
- if (fEmbedding)
- return FALSE;
- else
- {
- char sz[100];
- wsprintf (sz, "File %s not found.", (LPSTR) szBuf);
- ErrorBox (sz);
- return CreateUntitledDoc(nCmdShow);
- }
- }
-
- if (!CreateDocFromFile (szBuf, NULL, doctypeFromFile))
- {
- // File not in proper format.
- if (fEmbedding)
- return FALSE;
- else
- {
- char sz[100];
- wsprintf (sz, "File %s not in proper format.", (LPSTR) szBuf);
- ErrorBox (sz);
- return CreateUntitledDoc(nCmdShow);
- }
- }
- }
-
- if (fEmbedding)
- {
- /* Do not show window until told to do so by client. */
- ShowWindow(hwndMain, SW_HIDE);
- }
- else
- {
- ShowWindow(hwndMain, nCmdShow);
- UpdateWindow(hwndMain);
- }
- return TRUE;
- }
-
-
-
- /* SaveDimensions
- * --------------
- *
- * Save the dimensions of the main window in a private profile file.
- *
- * CUSTOMIZATION: This function may be removed. If you wish to support
- * intelligent window placement, then the only necessary
- * change is to change the string "SrvrDemo.Ini" to a filename
- * appropriate for your application.
- */
- static void SaveDimensions (void)
- {
- if ((dimsCurrent.nX != dimsSaved.nX) ||
- (dimsCurrent.nY != dimsSaved.nY) ||
- (dimsCurrent.nWidth != dimsSaved.nWidth) ||
- (dimsCurrent.nHeight != dimsSaved.nHeight) )
- {
- // Save current window dimensions to private profile.
- char szBuf[7];
- wsprintf (szBuf, "%d", dimsCurrent.nX);
- WritePrivateProfileString
- (szAppName, "x", szBuf, "SrvrDemo.Ini");
- wsprintf (szBuf, "%d", dimsCurrent.nY);
- WritePrivateProfileString
- (szAppName, "y", szBuf, "SrvrDemo.Ini");
- wsprintf (szBuf, "%d", dimsCurrent.nWidth);
- WritePrivateProfileString
- (szAppName, "w", szBuf, "SrvrDemo.Ini");
- wsprintf (szBuf, "%d", dimsCurrent.nHeight);
- WritePrivateProfileString
- (szAppName, "h", szBuf, "SrvrDemo.Ini");
- }
- }
-
-
-
- /* SelectedObject
- * --------------
- *
- * Return a pointer to the currently selected object.
- *
- * CUSTOMIZATION: What a "selected object" is will vary from application
- * to application. You may find it useful to have a function
- * like this. In your application it may be necessary to
- * actually create an OBJ structure based on what data the
- * user has selected from the document (by highlighting some
- * text for example).
- *
- */
- LPOBJ SelectedObject (void)
- {
- return HwndToLpobj (SelectedObjectWindow());
- }
-
-
-
-
- /* SelectedObjectWindow
- * --------------------
- *
- * Return a handle to the window for the currently selected object.
- * The GetWindow calls returns a handle to the main window's first child,
- * which is the selected object's window.
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- HWND SelectedObjectWindow (void)
- {
- return GetWindow (hwndMain, GW_CHILD);
- }
-
-
-
- /* SetHiMetricFields
- * -----------------
- *
- * Adjust the nHiMetricWidth and nHiMetricHeight fields of a NATIVE structure
- * so that they are equivalent to the nWidth and nHeight fields.
- * The negative sign in the last line is necessary because the positive
- * y direction is toward the top of the screen in MM_HIMETRIC mode.
- *
- * LPOBJ lpobj - Pointer to the object whose native data will be adjusted
- *
- * CUSTOMIZATION: Server Demo specific, although you may need a function like
- * this if you keep track of the size of an object, and an
- * object handler needs to know the object's size in
- * HiMetric units.
- *
- *
- */
- void SetHiMetricFields (LPOBJ lpobj)
- {
- POINT pt;
-
- pt.x = lpobj->native.nWidth;
- pt.y = lpobj->native.nHeight;
- DeviceToHiMetric (hwndMain, &pt);
- lpobj->native.nHiMetricWidth = pt.x;
- lpobj->native.nHiMetricHeight = pt.y;
- }
-
-
-
- /* SkipBlanks
- * ----------
- *
- * LPSTR *plpsz - Pointer to a pointer to a character
- *
- * Increment *plpsz past any blanks in the character string.
- * This function is used in ProcessCmdLine.
- *
- */
- static void SkipBlanks (LPSTR *plpsz)
- {
- while (**plpsz && **plpsz == ' ')
- (*plpsz)++;
- }
-
-
-
- /* UpdateObjMenus
- * ---------------
- *
- * Grey or Ungrey menu items depending on the existence of at least one
- * object in the document.
- *
- * CUSTOMIZATION: Server Demo specific
- *
- */
- static void UpdateObjMenus (void)
- {
- static BOOL fObjMenusEnabled = TRUE;
- BOOL fOneObjExists; // Does at least one object exist?
- WORD wEnable;
- HMENU hMenu;
-
- fOneObjExists = (SelectedObjectWindow() != NULL);
- if (fOneObjExists == fObjMenusEnabled)
- {
- // Nothing has changed.
- return;
- }
-
- wEnable = (fOneObjExists ? MF_ENABLED : MF_GRAYED);
-
- hMenu = GetMenu(hwndMain);
- EnableMenuItem(hMenu, menuposColor, MF_BYPOSITION | wEnable);
-
- hMenu = GetSubMenu(GetMenu(hwndMain), menuposFile);
- EnableMenuItem(hMenu, IDM_SAVE, MF_BYCOMMAND | wEnable);
- EnableMenuItem(hMenu, IDM_SAVEAS, MF_BYCOMMAND | wEnable);
-
- hMenu = GetSubMenu(GetMenu(hwndMain), menuposEdit);
- EnableMenuItem(hMenu, IDM_CUT, MF_BYCOMMAND | wEnable);
- EnableMenuItem(hMenu, IDM_COPY, MF_BYCOMMAND | wEnable);
- EnableMenuItem(hMenu, IDM_DELETE, MF_BYCOMMAND | wEnable);
-
- hMenu = GetSubMenu(GetMenu(hwndMain), menuposObject);
- EnableMenuItem(hMenu, IDM_NEXTOBJ, MF_BYCOMMAND | wEnable);
-
- DrawMenuBar (hwndMain);
- fObjMenusEnabled = fOneObjExists;
- }
-
-
-
- /* Wait
- * ----
- *
- * Dispatch messages until the given flag is set to FALSE.
- * One use of this function is to wait until a Release method is called
- * after a function has returned OLE_WAIT_FOR_RELEASE.
- *
- * BOOL *pf - Pointer to the flag being waited on.
- *
- * CUSTOMIZATION: The use of OleUnblockServer is for illustration only.
- * Since Server Demo does not call OleBlockServer, there
- * will never be any messages in the OLE queue.
- *
- */
- void Wait (BOOL *pf)
- {
- MSG msg;
- BOOL fMoreMsgs = FALSE;
-
- *pf = TRUE;
- while (*pf==TRUE)
- {
- OleUnblockServer (srvrMain.lhsrvr, &fMoreMsgs);
- if (!fMoreMsgs)
- // if there are no more messages in the OLE queue, go to system queue
- {
- if (GetMessage (&msg, NULL, NULL, NULL))
- {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
- }
- }
- }
-
- static BOOL FailedUpdate(HWND hwnd)
- {
- BOOL bRet;
- FARPROC lpfn;
-
- lpfn = MakeProcInstance(fnFailedUpdate,hInst);
- bRet = DialogBox(hInst, "FailedUpdate", hwnd, lpfn);
- FreeProcInstance(lpfn);
- return(bRet);
-
- }
-
- BOOL FAR PASCAL fnFailedUpdate (HWND hDlg, WORD message, WORD wParam, DWORD lParam)
- {
-
- switch (message)
- {
- case WM_COMMAND:
- switch (wParam)
- {
- case IDCANCEL:
- case IDD_CONTINUEEDIT:
- EndDialog(hDlg, TRUE);
- break;
-
- case IDD_UPDATEEXIT:
- EndDialog(hDlg, FALSE);
- break;
-
- default:
- break;
- }
- break;
-
- case WM_INITDIALOG:
- {
- char szMsg[200];
-
- szMsg[0] = NULL;
-
- wsprintf(
- szMsg,
- "This %s document can only be updated when you exit %s.",
- (LPSTR) szClient,
- (LPSTR) szAppName
- );
-
- SetDlgItemText(hDlg, IDD_TEXT, szMsg);
- return TRUE;
- }
-
- default:
- break;
- }
-
- return FALSE;
- }
-