Annotation of mstools/samples/ole/srvrdemo/srvrdemo.c, revision 1.1.1.2

1.1       root        1: /*                     
                      2:   OLE SERVER DEMO
                      3:   SrvrDemo.c                                               
                      4:                                                                          
                      5:   This file contains the window handlers, and various initialization and
                      6:   utility functions.
                      7:                                                                          
                      8:   (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved        
                      9: */
                     10: 
                     11: 
                     12: #define SERVERONLY
                     13: #include <windows.h>
                     14: #include <ole.h>
                     15: 
                     16: #include "srvrdemo.h"
                     17: 
                     18: /* Global variable definitions */
                     19: 
                     20: HWND   hwndMain = NULL;
                     21: 
1.1.1.2 ! root       22: // Used in converting units from pixels to Himetric and vice-versa
        !            23: int    giXppli = NULL;       // pixels per logical inch along width
        !            24: int    giYppli = NULL;       // pixels per logical inch along height 
        !            25: 
        !            26: 
        !            27: 
1.1       root       28: // Since this is a not an MDI app, there can be only one server and one doc.
                     29: SRVR   srvrMain;
                     30: DOC    docMain;
                     31: CHAR   szClient[cchFilenameMax];
                     32: CHAR   szClientDoc[cchFilenameMax];
                     33: 
                     34: // Has the user made changes to the document? 
                     35: BOOL   fDocChanged = FALSE;
                     36: 
                     37: // Is this the first instance of this application currently running? 
                     38: BOOL   fFirstInstance = TRUE;
                     39: 
                     40: // This flag is used when OleRevokeServerDoc returns OLE_WAIT_FOR_RELEASE,
                     41: // and we must wait until DocRelease is called.
                     42: BOOL   fWaitingForDocRelease = FALSE;
                     43: 
                     44: // This flag is used when OleRevokeServer returns OLE_WAIT_FOR_RELEASE,
                     45: // and we must wait until SrvrRelease is called.
                     46: BOOL   fWaitingForSrvrRelease = FALSE;
                     47: 
                     48: // This flag is set to TRUE after an application has called OleBlockServer
                     49: // and now wishes to unblock the queued messages.  See WinMain.
                     50: // Server Demo never sets fUnblock to TRUE because it never calls 
                     51: // OleBlockServer.
                     52: BOOL fUnblock = FALSE;
                     53: 
                     54: // Set this to FALSE if you want to guarantee that the server will not revoke
                     55: // itself when SrvrRelease is called.  This is used in the IDM_NEW case and
                     56: // the IDM_OPEN case (in OpenDoc).
                     57: BOOL fRevokeSrvrOnSrvrRelease = TRUE;
                     58: 
                     59: // Version number, which is stored in the native data.
                     60: VERSION version = 1;
                     61: 
                     62: HBRUSH hbrColor[chbrMax];
                     63: 
                     64: // Clipboard formats
                     65: OLECLIPFORMAT cfObjectLink;
                     66: OLECLIPFORMAT cfOwnerLink;
                     67: OLECLIPFORMAT cfNative;
                     68: 
                     69: // Method tables.
                     70: OLESERVERDOCVTBL docvtbl;
                     71: OLEOBJECTVTBL    objvtbl;
                     72: OLESERVERVTBL    srvrvtbl;
                     73: 
                     74: HANDLE hInst;
                     75: HANDLE hAccelTable;
                     76: HMENU  hMainMenu = NULL;
                     77: 
                     78: // Window dimensions saved in private profile.
                     79: static struct
                     80: {
                     81:    INT nX;
                     82:    INT nY;
                     83:    INT nWidth;
                     84:    INT nHeight;
                     85: } dimsSaved, dimsCurrent;
                     86: 
                     87: 
                     88: static enum
                     89: {
                     90:    // Corresponds to the order of the menus in the .rc file.
                     91:    menuposFile,
                     92:    menuposEdit,
                     93:    menuposColor,
                     94:    menuposObject
                     95: };               
                     96: 
                     97: 
                     98: // Static functions.
                     99: static VOID  DeleteInstance (VOID);
                    100: static BOOL  ExitApplication (BOOL);
                    101: static VOID  GetWord (LPSTR *plpszSrc, LPSTR lpszDst);
                    102: static BOOL  InitApplication( HANDLE hInstance);
                    103: static BOOL  InitInstance (HANDLE hInstance);
                    104: static BOOL  ProcessCmdLine (LPSTR,HWND);
                    105: static VOID  SaveDimensions (VOID);
                    106: static VOID  SkipBlanks (LPSTR *plpsz);
                    107: static VOID  UpdateObjMenus (VOID);
                    108: static BOOL  FailedUpdate(HWND);
                    109: 
                    110: /* WinMain
                    111:  * -------
                    112:  *
                    113:  * Standard windows entry point
                    114:  *
                    115:  * CUSTOMIZATION: None
                    116:  *
                    117:  */
1.1.1.2 ! root      118: int APIENTRY WinMain(
1.1       root      119:    HANDLE hInstance,
                    120:    HANDLE hPrevInstance,
                    121:    LPSTR  lpCmdLine,
                    122:    INT    nCmdShow  
                    123: ){
                    124:     MSG    msg;
                    125: 
                    126:     if (!InitApplication(hInstance))
                    127:       return FALSE;
                    128: 
                    129:     msg.wParam = FALSE;
                    130:     
                    131:     if (!InitInstance(hInstance))
                    132:         goto errRtn;
                    133: 
                    134:     if (!InitServer (hwndMain, hInstance))
                    135:         goto errRtn;
                    136: 
                    137:     if (!ProcessCmdLine(lpCmdLine,hwndMain))
                    138:     {
                    139:         ExitApplication(FALSE);
                    140:         goto errRtn;
                    141:     }
                    142: 
                    143:     for (;;)
                    144:     {
                    145:          // Your application should set fUnblock to TRUE when it decides
                    146:          // to unblock.
                    147:          if (fUnblock)
                    148:          {
                    149:             BOOL fMoreMsgs = TRUE;
                    150:             while (fMoreMsgs)
                    151:             {
                    152:                OleUnblockServer (srvrMain.lhsrvr, &fMoreMsgs);
                    153:             }
                    154:             // We have taken care of all the messages in the OLE queue
                    155:             fUnblock = FALSE;
                    156:          }
                    157:       
                    158:          if (!GetMessage(&msg, NULL, NULL, NULL)) 
                    159:             break;
                    160:          if( !TranslateAccelerator(hwndMain, hAccelTable, &msg)) 
                    161:          {
                    162:                TranslateMessage(&msg);
                    163:                DispatchMessage(&msg); 
                    164:          }
                    165:     }
                    166: 
                    167:     
                    168: errRtn:
                    169: 
                    170:     DeleteInstance ();
                    171:     return (msg.wParam);
                    172: }
                    173: 
                    174: 
                    175: 
                    176: /* InitApplication
                    177:  * ---------------
                    178:  *
                    179:  * Initialize the application - register the window classes
                    180:  *
                    181:  * HANDLE hInstance
                    182:  * 
                    183:  * RETURNS: TRUE if classes are properly registered.
                    184:  *          FALSE otherwise
                    185:  *
                    186:  * CUSTOMIZATION: Re-implement
                    187:  *
                    188:  */
                    189: static BOOL InitApplication( HANDLE hInstance )
                    190: {
                    191:     WNDCLASS  wc;
                    192: 
                    193:     wc.lpszClassName = "MainClass";
                    194:     wc.lpfnWndProc   = (WNDPROC)MainWndProc;
                    195:     wc.style         = NULL;
                    196:     wc.cbClsExtra    = 4;
                    197:     wc.cbWndExtra    = 0;
                    198:     wc.hInstance     = hInstance;
                    199:     wc.hIcon         = LoadIcon(hInstance, "DocIcon");
                    200:     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
                    201:     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
                    202:     wc.lpszMenuName  = "MainMenu";
                    203: 
                    204:     if (!RegisterClass(&wc))
                    205:         return FALSE;
                    206: 
                    207:     wc.lpszClassName = "ObjClass";
                    208:     wc.lpfnWndProc   = (WNDPROC)ObjWndProc;
                    209:     wc.hIcon         = NULL;
                    210:     wc.cbWndExtra    = cbWindExtra;
                    211:     wc.lpszMenuName  = NULL;
                    212:     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
                    213: 
                    214:     if (!RegisterClass(&wc))
                    215:         return FALSE;
                    216: 
                    217:     return TRUE;
                    218: }
                    219: 
                    220: 
                    221: 
                    222: /* InitInstance
                    223:  * ------------
                    224:  *
                    225:  * Create brushes used by the program, the main window, and 
                    226:  * do any other per-instance initialization.
                    227:  *
                    228:  * HANDLE hInstance
                    229:  * 
                    230:  * RETURNS: TRUE if successful 
                    231:  *          FALSE otherwise.
                    232:  *
                    233:  * CUSTOMIZATION: Re-implement
                    234:  *
                    235:  */
                    236: static BOOL InitInstance (HANDLE hInstance)
                    237: {
                    238:     LONG rglColor [chbrMax] = 
                    239:     {
                    240:       0x000000ff,  // Red
                    241:       0x0000ff00,  // Green
                    242:       0x00ff0000,  // Blue
                    243:       0x00ffffff,  // White
                    244:       0x00808080,  // Gray
                    245:       0x00ffff00,  // Cyan
                    246:       0x00ff00ff,  // Magenta
                    247:       0x0000ffff   // Yellow
                    248:     };
                    249: 
                    250: 
                    251:     INT iColor;
1.1.1.2 ! root      252:         HDC hDC ;
1.1       root      253:     
                    254:     hInst = hInstance;
                    255: 
                    256:     // Initialize the method tables.
                    257:     InitVTbls ();
                    258: 
                    259:     // Initialize the brushes used.
                    260:     for (iColor = 0; iColor < chbrMax; iColor++)
                    261:       hbrColor[iColor] = CreateSolidBrush (rglColor[iColor]);
                    262: 
                    263:     // Register clipboard formats.
                    264:     cfObjectLink= RegisterClipboardFormat ("ObjectLink");
                    265:     cfOwnerLink = RegisterClipboardFormat ("OwnerLink");
                    266:     cfNative    = RegisterClipboardFormat ("Native");
                    267: 
                    268:     hAccelTable = LoadAccelerators(hInst, "Accelerators");
                    269: //    hMainMenu   = LoadMenu(hInst, "MainMenu");
                    270: 
                    271: 
                    272:     hwndMain = CreateWindow(
                    273:         "MainClass",
                    274:         szAppName,
                    275:         WS_OVERLAPPEDWINDOW,
                    276:         CW_USEDEFAULT, CW_USEDEFAULT,
                    277:         3*OBJECT_WIDTH, 3*OBJECT_HEIGHT,
                    278:         NULL,
                    279:         NULL,
                    280:         hInstance,
                    281:         NULL
                    282:     );
                    283: 
                    284: 
                    285:     if (!hwndMain)
                    286:         return FALSE;
                    287: 
                    288:     szClient[0] = NULL;
                    289:     lstrcpy (szClientDoc, "Client Document");
                    290:     
                    291:     // Initialize global variables with LOGPIXELSX and LOGPIXELSY
                    292:         
1.1.1.2 ! root      293:     hDC    = GetDC (NULL);       // Get the hDC of the desktop window
        !           294:     giXppli = GetDeviceCaps (hDC, LOGPIXELSX);
        !           295:     giYppli = GetDeviceCaps (hDC, LOGPIXELSY);
        !           296:     ReleaseDC (NULL, hDC);
        !           297:         
        !           298:         
1.1       root      299:     return TRUE;
                    300: 
                    301: }
                    302: 
                    303: 
                    304: 
                    305: /* DeleteInstance
                    306:  * --------------
                    307:  *
                    308:  * Deallocate the VTables, and the brushes created for this instance
                    309:  *
                    310:  *
                    311:  * CUSTOMIZATION: The call to FreeVTbls must remain.
                    312:  *
                    313:  */
                    314: static VOID DeleteInstance (VOID)
                    315: {
                    316:     INT i;
                    317: 
                    318:     for (i = 0; i < chbrMax; i++)
                    319:         DeleteObject (hbrColor[i]);
                    320: 
                    321: }
                    322: 
                    323: 
                    324: 
                    325: /* ExitApplication
                    326:  * ---------------
                    327:  *
                    328:  * Handles the WM_CLOSE and WM_COMMAND/IDM_EXIT messages.
                    329:  *
                    330:  * RETURNS: TRUE if application should really terminate
                    331:  *          FALSE if not
                    332:  *
                    333:  *
                    334:  * CUSTOMIZATION: None
                    335:  *
                    336:  */
                    337: static BOOL ExitApplication (BOOL fUpdateLater)
                    338: {
                    339: 
                    340:    if (fUpdateLater)
                    341:    {
                    342:       // The non-standard OLE client did not accept the update
                    343:       // when we requested it, so we are sending the client 
                    344:       // OLE_CLOSED now that we are closing the document.
                    345:       SendDocMsg (OLE_CLOSED);
                    346:    }
                    347: 
                    348:    if (StartRevokingServer() == OLE_WAIT_FOR_RELEASE)
                    349:       Wait (&fWaitingForSrvrRelease);
                    350:    /* SrvrRelease will not necessarily post a WM_QUIT message.
                    351:       If the document is not embedded, SrvrRelease by itself does
                    352:       not cause the application to terminate.  But now we want it to.
                    353:    */
                    354:    if (docMain.doctype != doctypeEmbedded)
                    355:       PostQuitMessage(0);
                    356:    SaveDimensions();
                    357:    return TRUE;
                    358: }
                    359: 
                    360: 
                    361: 
                    362: /* MainWndProc
                    363:  * -----------
                    364:  *
                    365:  * Main window message handler.
                    366:  *
                    367:  *
                    368:  * CUSTOMIZATION: Remove the color menu and the object menu entirely.  
                    369:  *                Add handlers for your application's menu items and any 
                    370:  *                Windows messages your application needs to handle.  
                    371:  *                The handlers for the menu items that involve OLE
                    372:  *                can be added to, but no logic should be removed.
                    373:  *                    
                    374:  *
                    375:  */
                    376: LONG  APIENTRY MainWndProc
1.1.1.2 ! root      377:    (HWND hwnd, UINT message, WPARAM wParam, LONG lParam )
1.1       root      378: {
                    379:     LPOBJ     lpobj;
                    380: 
                    381:     switch (message) 
                    382:     {
                    383:         case WM_COMMAND:
                    384:         {
                    385:             WORD wID = LOWORD(wParam);
                    386: 
                    387:             if (fWaitingForDocRelease)
                    388:             {
                    389:                ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
                    390:                return NULL;
                    391:             }
                    392: 
                    393:             switch (wID) 
                    394:             {
                    395:                case IDM_EXIT:
                    396:                   SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
                    397:                   break;
                    398: 
                    399:                case IDM_ABOUT:
1.1.1.2 ! root      400:                   DialogBox(hInst, "AboutBox", hwnd, (DLGPROC)About);
1.1       root      401:                   break;
                    402:    
                    403:                case IDM_NEW:
                    404:                {
                    405:                   BOOL fUpdateLater;
                    406:                   OLESTATUS olestatus;
                    407: 
                    408:                   if (SaveChangesOption (&fUpdateLater) == IDCANCEL)
                    409:                      break;
                    410:                   else if (fUpdateLater)
                    411:                      SendDocMsg (OLE_CLOSED);
                    412: 
                    413:                   // We want to revoke the doc but not the server, so if
                    414:                   // SrvrRelease is called, do not revoke server.
                    415:                   fRevokeSrvrOnSrvrRelease = FALSE;
                    416: 
                    417:                   if ((olestatus = RevokeDoc()) > OLE_WAIT_FOR_RELEASE) 
                    418:                   {   
                    419:                      ErrorBox ("Serious Error: Cannot revoke document.");
                    420:                      break;
                    421:                   }
                    422:                   else if (olestatus == OLE_WAIT_FOR_RELEASE)
                    423:                      Wait (&fWaitingForDocRelease);
                    424:   
                    425:                   fRevokeSrvrOnSrvrRelease = TRUE;
                    426: 
                    427:                   if (!CreateNewDoc (NULL, "(Untitled)", doctypeNew))
                    428:                   {
                    429:                      ErrorBox ("Serious Error: Cannot create new document.");
                    430:                      break;
                    431:                   }
                    432:                   // Your application need not create a default object.
                    433:                   CreateNewObj (FALSE);
                    434:                   EmbeddingModeOff();
                    435:                   break;
                    436:                }
                    437:                case IDM_OPEN:
                    438:                   OpenDoc();
                    439:                   UpdateObjMenus();
                    440:                   break;
                    441: 
                    442:                case IDM_SAVE:
                    443:                   SaveDoc();
                    444:                   break;
                    445: 
                    446:                case IDM_SAVEAS:
                    447:                   if (!SaveDocAs ())
                    448:                      break;
                    449:                   if (docMain.doctype != doctypeEmbedded)
                    450:                      EmbeddingModeOff();
                    451:                   break;
                    452: 
                    453:                case IDM_UPDATE:
                    454:                   switch (OleSavedServerDoc (docMain.lhdoc))
                    455:                   {
                    456:                      case OLE_ERROR_CANT_UPDATE_CLIENT:
                    457:                         if (!FailedUpdate(hwnd))
                    458:                            ExitApplication(TRUE);
                    459:                         break;
                    460:                      case OLE_OK:
                    461:                         break;
                    462:                      default:
                    463:                         ErrorBox ("Serious Error: Cannot update.");
                    464:                   }
                    465:                   break;
                    466: 
                    467:                /* Color menu */
                    468: 
                    469:                case IDM_RED:
                    470:                case IDM_GREEN:
                    471:                case IDM_BLUE:
                    472:                case IDM_WHITE:
                    473:                case IDM_GRAY:
                    474:                case IDM_CYAN:
                    475:                case IDM_MAGENTA:
                    476:                case IDM_YELLOW:
                    477:                   lpobj = SelectedObject();
                    478:                   lpobj->native.idmColor = wID;
                    479:                   // Recolor the object on the screen.
                    480:                   InvalidateRect (lpobj->hwnd, (LPRECT)NULL,  TRUE);
                    481:                   UpdateWindow (lpobj->hwnd);
                    482:                   fDocChanged = TRUE;
                    483:                   if (docMain.doctype == doctypeFromFile)
                    484:                      // If object is linked, update it in client now. 
                    485:                      SendObjMsg (lpobj, OLE_CHANGED);
                    486:                   break;
                    487: 
                    488:                /* Edit menu */
                    489: 
                    490:                case IDM_COPY:
                    491:                   CutOrCopyObj (TRUE);
                    492:                   break;
                    493: 
                    494:                case IDM_CUT:
                    495:                   CutOrCopyObj (FALSE);
                    496:                   // Fall through.
                    497: 
                    498:                case IDM_DELETE:
                    499:                   RevokeObj (SelectedObject());
                    500:                   DestroyWindow (SelectedObjectWindow());
                    501:                   UpdateObjMenus();
                    502:                   break;
                    503: 
                    504:                /* Object menu */
                    505: 
                    506:                case IDM_NEXTOBJ:
                    507:                   lpobj = SelectedObject();
                    508:                   /* The 1 in the second parameter puts the current window
                    509:                      at the bottom of the current window list. */
                    510:                   SetWindowPos(lpobj->hwnd, (HANDLE)1, 0,0,0,0,
                    511:                               SWP_NOMOVE | SWP_NOSIZE);
                    512:                   break;
                    513: 
                    514:                case IDM_NEWOBJ:
                    515:                   lpobj = CreateNewObj (TRUE);
                    516:                   BringWindowToTop(lpobj->hwnd);
                    517:                   break;
                    518: 
                    519:                default:
                    520:                   ErrorBox ("Unknown Command.");
                    521:                   break;
                    522:             }         
                    523:             break;
                    524:          }
                    525: 
                    526:         case WM_NCCALCSIZE:
                    527:             if (!IsIconic(hwnd) && !IsZoomed(hwnd))
                    528:             {
                    529:                 dimsCurrent.nX = ((LPRECT)lParam)->left;
                    530:                 dimsCurrent.nWidth = ((LPRECT)lParam)->right - dimsCurrent.nX;
                    531:                 dimsCurrent.nY = ((LPRECT)lParam)->top;
                    532:                 dimsCurrent.nHeight = ((LPRECT)lParam)->bottom - dimsCurrent.nY;
                    533:             }
                    534:             return DefWindowProc(hwnd, message, wParam, lParam);
                    535:             break;
                    536: 
                    537:         case WM_QUERYENDSESSION:
                    538:         {
                    539:             BOOL fUpdateLater;
                    540: 
                    541:             if (SaveChangesOption(&fUpdateLater) == IDCANCEL)
                    542:                return FALSE;
                    543: 
                    544:             if (fUpdateLater)
                    545:             {
                    546:                // The non-standard OLE client did not accept the update
                    547:                // when we requested it, so we are sending the client 
                    548:                // OLE_CLOSED now that we are closing the document.
                    549:                SendDocMsg (OLE_CLOSED);
                    550:             }                          
                    551:             return TRUE;
                    552:         }
                    553: 
                    554:         case WM_CLOSE:
                    555:          {
                    556:             BOOL fUpdateLater;
                    557: 
                    558:             if (SaveChangesOption(&fUpdateLater) != IDCANCEL)
                    559:                ExitApplication(fUpdateLater);
                    560:             break;
                    561:          }
                    562: 
                    563:         default:
                    564:             return DefWindowProc(hwnd, message, wParam, lParam);
                    565:     }
                    566:     return NULL;
                    567: }
                    568: 
                    569: 
                    570: 
                    571: /* About
                    572:  * -----
                    573:  *
                    574:  * "About Box" dialog handler.
                    575:  *
                    576:  * CUSTOMIZATION: None
                    577:  *
                    578:  */
1.1.1.2 ! root      579: BOOL  APIENTRY About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root      580: {
                    581:     switch (message) 
                    582:     {
                    583:         case WM_INITDIALOG:
                    584:             return TRUE;
                    585: 
                    586:         case WM_COMMAND:
                    587:         {
                    588:             WORD wID = LOWORD(wParam);
                    589: 
                    590:             if (wID == IDOK || wID == IDCANCEL) 
                    591:             {
                    592:                 EndDialog(hDlg, TRUE);
                    593:                 return TRUE;
                    594:             }
                    595:             break;
                    596:         }
                    597:     }
                    598:     return FALSE;
                    599: }
                    600: 
                    601: 
                    602: 
                    603: 
                    604: /* ObjWndProc
                    605:  * ----------
                    606:  *
                    607:  * Message handler for the object windows.
                    608:  *
                    609:  *
                    610:  * CUSTOMIZATION: Server Demo specific
                    611:  *
                    612:  */
                    613: LONG  APIENTRY ObjWndProc 
1.1.1.2 ! root      614:    (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root      615: {
                    616:     static BOOL    fCapture = FALSE;
                    617:     static struct  {RECT rect; POINT pt;} drag;
                    618:     static RECT    rectMain;
                    619: 
                    620:     switch (message) 
                    621:     {
                    622:         case WM_CREATE:
                    623:         {
                    624:             LPOBJ          lpobj;
                    625:             LPCREATESTRUCT lpcs;
                    626:             // The call to CreateWindow puts lpobj into lpCreateParams
                    627:             lpcs = (LPCREATESTRUCT) lParam;
                    628:             lpobj = (LPOBJ) lpcs->lpCreateParams;
                    629:             // Associate the window just created with the object.
                    630:             lpobj->hwnd = hwnd;
                    631:             /* Store pointer to object in the window structure. */
                    632:             SetWindowLong(hwnd, ibLpobj, (LONG) lpobj);
                    633:             UpdateObjMenus ();
                    634:             break;
                    635:         }
                    636:         case WM_SIZE:
                    637:         {
                    638:             RECT rect;
                    639:             if (fWaitingForDocRelease)
                    640:             {   
                    641:                ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
                    642:                return NULL;
                    643:             }
                    644:             // Get coordinates of object relative to main window's client area.
                    645:             GetWindowRect (hwnd, (LPRECT)&rect);
                    646:             ScreenToClient (hwndMain, (LPPOINT)&rect);
                    647:             ScreenToClient (hwndMain, (LPPOINT)&rect.right);
                    648:             SizeObj (hwnd, rect, TRUE);
                    649:             // Fall through.
                    650:         }
                    651:         case WM_PAINT:
                    652:             PaintObj (hwnd);
                    653:             break;
                    654: 
                    655:         case WM_LBUTTONDOWN:
                    656:             if (fWaitingForDocRelease)
                    657:             {   
                    658:                ErrorBox ("Waiting for a document to be revoked.\n\rPlease wait.");
                    659:                return NULL;
                    660:             }
                    661:             BringWindowToTop (hwnd);
                    662: 
                    663:             GetWindowRect (hwnd, (LPRECT) &drag.rect);
                    664:             ScreenToClient (hwndMain, (LPPOINT)&drag.rect.left);
                    665:             ScreenToClient (hwndMain, (LPPOINT)&drag.rect.right);
                    666: 
                    667:             drag.pt.x = LOWORD(lParam);
                    668:             drag.pt.y = HIWORD(lParam);
                    669: 
                    670:             // Convert drag.pt to the main window's client coordinates.
                    671:             ClientToScreen (hwnd, (LPPOINT)&drag.pt);
                    672:             ScreenToClient (hwndMain, (LPPOINT)&drag.pt);
                    673: 
                    674:             // Remember the coordinates of the main window so we do not drag
                    675:             // an object outside the main window.
                    676:             GetClientRect (hwndMain, (LPRECT) &rectMain);
                    677: 
                    678:             SetCapture (hwnd);
                    679:             fCapture = TRUE;
                    680:             break;
                    681: 
                    682:         case WM_MOUSEMOVE:
                    683:         {
                    684:             HDC   hdc;
                    685:             POINT pt;
                    686: 
                    687:             if (!fCapture)
                    688:                 break;
                    689: 
                    690:             fDocChanged = TRUE;
                    691:             pt.x = LOWORD(lParam);
                    692:             pt.y = HIWORD(lParam);
                    693: 
                    694:             // Convert pt to the main window's client coordinates.
                    695:             ClientToScreen (hwnd, (LPPOINT)&pt);
                    696:             ScreenToClient (hwndMain, (LPPOINT)&pt);
                    697: 
                    698:             if (!PtInRect (&rectMain, pt))
                    699:                break;
                    700: 
                    701:             hdc = GetDC(hwndMain);
                    702: 
                    703:             // Erase old drag rectangle
                    704:             InvertRect (hdc, (LPRECT)&drag.rect);
                    705:                   
                    706:             // Update drag.rect
                    707:             OffsetRect (&drag.rect, pt.x - drag.pt.x, pt.y - drag.pt.y);
                    708: 
                    709:             // Update drag.pt
                    710:             drag.pt.x = pt.x;
                    711:             drag.pt.y = pt.y;
                    712: 
                    713:             // Show new drag rectangle
                    714:             InvertRect (hdc, (LPRECT)&drag.rect);
                    715:             ReleaseDC (hwndMain, hdc);
                    716:             break;
                    717:         }
                    718: 
                    719:         case WM_LBUTTONUP:
                    720:         {
                    721:             LPOBJ          lpobj;
                    722:             if (!fCapture)
                    723:                 return TRUE;
                    724: 
                    725:             fCapture = FALSE;
                    726:             ReleaseCapture ();
                    727: 
                    728:             MoveWindow (hwnd, drag.rect.left, drag.rect.top,
                    729:                         drag.rect.right - drag.rect.left,
                    730:                         drag.rect.bottom - drag.rect.top, TRUE);
                    731:             InvalidateRect (hwnd, (LPRECT)NULL, TRUE);
                    732:             lpobj = HwndToLpobj (hwnd);
                    733:             lpobj->native.nX = drag.rect.left;
                    734:             lpobj->native.nY = drag.rect.top;
                    735:             break;
                    736:         }
                    737:         case WM_DESTROY:
                    738:             DestroyObj (hwnd);
                    739:             return DefWindowProc(hwnd, message, wParam, lParam);
                    740: 
                    741:         default:
                    742:             return DefWindowProc(hwnd, message, wParam, lParam);
                    743:     }
                    744:     return NULL;
                    745: }
                    746: 
                    747: 
                    748: 
                    749: /* DeviceToHiMetric
                    750:  * ----------------
                    751:  *
                    752:  * Converts a point from device units to HiMetric units.
                    753:  * This function is designed to be generic enough to be reused.
                    754:  *
                    755:  * HWND hwnd    - The window whose display context is to be used
                    756:  * LPPOINT lppt - The point to be converted.
                    757:  *
                    758:  * CUSTOMIZATION: None
                    759:  *
                    760:  */
1.1.1.2 ! root      761: void DeviceToHiMetric ( LPPOINT lppt)
1.1       root      762: {
1.1.1.2 ! root      763:     lppt->x = MulDiv (lppt->x, HIMETRIC_PER_INCH, giXppli);
        !           764:     lppt->y = MulDiv (lppt->y, HIMETRIC_PER_INCH, giYppli);
1.1       root      765: }
                    766: 
                    767: 
                    768: /* UpdateFileMenu
                    769:  * --------------
                    770:  *
                    771:  * Updates the "Update <Client doc>" and "Exit & Return to <Client doc>" 
                    772:  * with the currently set client document name
                    773:  *
                    774:  * CUSTOMIZATION: Re-implement
                    775:  *
                    776:  */
                    777: VOID UpdateFileMenu (INT iSaveUpdateId)
                    778: {
                    779:     CHAR    str[cchFilenameMax];
                    780:     HMENU   hMenu = GetMenu(hwndMain);    
                    781: 
                    782:     /* Change File menu so it contains "Update" instead of "Save". */
                    783:     
                    784:     lstrcpy (str, "&Update ");
                    785:     lstrcat (str, szClientDoc);
                    786:     ModifyMenu(hMenu, iSaveUpdateId, MF_BYCOMMAND|MF_STRING, IDM_UPDATE, str);
                    787:     
                    788:     /* Change File menu so it contains "Exit & Return to <client doc>" */
                    789:     /* instead of just "Exit" */
                    790:     
                    791:     lstrcpy (str, "E&xit && Return to ");
                    792:     lstrcat (str, szClientDoc);
                    793:     ModifyMenu(hMenu, IDM_EXIT, MF_BYCOMMAND|MF_STRING, IDM_EXIT, str);
                    794: }
                    795: 
                    796: 
                    797: 
                    798: /* EmbeddingModeOn
                    799:  * ---------------
                    800:  *
                    801:  * Do whatever is necessary for the application to start "embedding mode."
                    802:  *
                    803:  * CUSTOMIZATION: Re-implement
                    804:  *
                    805:  */
                    806: VOID EmbeddingModeOn(VOID) 
                    807: {
                    808:     HMENU hMenu = GetMenu(hwndMain);
                    809: 
                    810:     UpdateFileMenu (IDM_SAVE);
                    811: 
                    812:     /* Change File menu so it contains "Save Copy As..." instead of */
                    813:     /* "Save As..." */
                    814:     ModifyMenu(hMenu, IDM_SAVEAS, MF_BYCOMMAND|MF_STRING, IDM_SAVEAS, 
                    815:         "Save Copy As..");
                    816:     
                    817:     /* In embedded mode, the user can edit only the embedded object, not
                    818:        create new ones. */
                    819:     EnableMenuItem(hMenu, menuposObject, MF_BYPOSITION | MF_GRAYED);
                    820:     EnableMenuItem(hMenu, IDM_CUT,     MF_BYCOMMAND | MF_GRAYED);
                    821:     EnableMenuItem(hMenu, IDM_DELETE,  MF_BYCOMMAND | MF_GRAYED);
                    822:     DrawMenuBar (hwndMain);
                    823: }
                    824: 
                    825: 
                    826: 
                    827: 
                    828: /* EmbeddingModeOff
                    829:  * ----------------
                    830:  *
                    831:  * Do whatever is necessary for the application to end "embedding mode."
                    832:  *
                    833:  * CUSTOMIZATION: Re-implement
                    834:  *
                    835:  */
                    836: VOID EmbeddingModeOff (VOID) 
                    837: {
                    838:     HMENU hMenu = GetMenu(hwndMain);
                    839: 
                    840:     /* Change File menu so it contains "Save" instead of "Update". */
                    841:     ModifyMenu(hMenu, IDM_UPDATE, MF_BYCOMMAND | MF_STRING, IDM_SAVE, "&Save");
                    842:     /* Change File menu so it contains "Exit & Return to <client doc>" */
                    843:     /* instead of just "Exit" */
                    844:     ModifyMenu(hMenu, IDM_EXIT, MF_BYCOMMAND | MF_STRING, IDM_EXIT, "E&xit");
                    845: 
                    846:     /* Change File menu so it contains "Save As..." instead of */
                    847:     /* "Save Copy As..." */
                    848:     ModifyMenu(hMenu, IDM_SAVEAS, MF_BYCOMMAND|MF_STRING, IDM_SAVEAS, 
                    849:         "Save As..");
                    850:     
                    851:     /* In non-embedded mode, the user can create new objects. */
                    852:     EnableMenuItem(hMenu, menuposObject, MF_BYPOSITION | MF_ENABLED);
                    853:     
                    854:     lstrcpy (szClientDoc, "Client Document");
                    855:     DrawMenuBar (hwndMain);
                    856: }
                    857: 
                    858: 
                    859: 
                    860: /* ErrorBox
                    861:  * --------
                    862:  *
                    863:  * char *szMessage - String to display inside message box.
                    864:  *
                    865:  * CUSTOMIZATION: Server Demo specific
                    866:  *
                    867:  */
                    868: VOID ErrorBox (CHAR *szMessage)
                    869: {
                    870:    MessageBox (hwndMain, szMessage, szAppName, MB_OK);
                    871: }
                    872: 
                    873: 
                    874: 
                    875: /* GetWord
                    876:  * -------
                    877:  *
                    878:  * LPSTR *plpszSrc - Pointer to a pointer to a source string
                    879:  * LPSTR lpszDst   - Pointer to destination buffer
                    880:  *
                    881:  * Will copy one space-terminated or null-terminated word from the source
                    882:  * string to the destination buffer.
                    883:  * When done, *plpszSrc will point to the character after the word. 
                    884:  * 
                    885:  * CUSTOMIZATION: Server Demo specific
                    886:  *
                    887:  */
                    888: static VOID GetWord (LPSTR *plpszSrc, LPSTR lpszDst)
                    889: {
                    890:    INT i = 0;
                    891:    while (**plpszSrc && **plpszSrc != ' ')
                    892:    {
                    893:          lpszDst[i++] = *(*plpszSrc)++;
                    894:    }
                    895:    lpszDst[i] = '\0';
                    896: }
                    897: 
                    898: 
                    899: 
                    900: /* HiMetricToDevice 
                    901:  * ----------------
                    902:  *
                    903:  * Converts a point from HiMetric units to device units.
                    904:  * This function is designed to be generic enough to be reused.
                    905:  *
                    906:  * HWND hwnd    - The window whose display context is to be used
                    907:  * LPPOINT lppt - The point to be converted.
                    908:  *
                    909:  * CUSTOMIZATION: None
                    910:  *
                    911:  */
1.1.1.2 ! root      912: void HiMetricToDevice ( LPPOINT lppt )
1.1       root      913: {
1.1.1.2 ! root      914:     lppt->x = MulDiv (giXppli, lppt->x, HIMETRIC_PER_INCH);
        !           915:     lppt->y = MulDiv (giYppli, lppt->y, HIMETRIC_PER_INCH);
1.1       root      916: }
                    917: 
                    918: 
                    919: 
                    920: /* HwndToLpobj
                    921:  * -----------
                    922:  *
                    923:  * Given an object's window, return a pointer to the object.
                    924:  * The GetWindowLong call extracts an LPOBJ from the extra data stored with
                    925:  * the window.
                    926:  *
                    927:  * HWND hwndObj - Handle to the object's window
                    928:  *
                    929:  * RETURNS: A pointer to the object
                    930:  *
                    931:  * CUSTOMIZATION: Server Demo specific
                    932:  *
                    933:  */
                    934: LPOBJ HwndToLpobj (HWND hwndObj)
                    935: {
                    936:    return (LPOBJ) GetWindowLong (hwndObj, ibLpobj);
                    937: }
                    938: 
                    939: 
                    940: 
                    941: /* CreateUntitledDoc
                    942:  * -----------------
                    943:  *
                    944:  * Create a fresh document with one object.
                    945:  *
                    946:  * RETURNS: TRUE if successful
                    947:  *          FALSE otherwise
                    948:  *
                    949:  * CUSTOMIZATION: Re-implement 
                    950:  *
                    951:  */
                    952: static BOOL CreateUntitledDoc (INT nCmdShow)
                    953: {
                    954:       if (!CreateNewDoc (NULL, "(Untitled)", doctypeNew))
                    955:          return FALSE;
                    956:       CreateNewObj (FALSE);
                    957:       ShowWindow(hwndMain, nCmdShow);
                    958:       UpdateWindow(hwndMain);
                    959:       return TRUE;
                    960: }
                    961: 
                    962: 
                    963: /* ProcessCmdLine
                    964:  * --------------
                    965:  *
                    966:  * Parses the Windows command line which was passed to WinMain.
                    967:  *
                    968:  * Case One: SrvrDemo.exe 
                    969:  *   fEmbedding = FALSE
                    970:  *   Create an untitled document.
                    971:  *
                    972:  * Case two: SrvrDemo.exe filename
                    973:  *   fEmbedding = FALSE
                    974:  *   Create a new document from the file.
                    975:  *
                    976:  * Case three: SrvrDemo.exe -Embedding
                    977:  *   fEmbedding = TRUE
                    978:  *   Do not create or register a document.
                    979:  *   Do not show window until client requests it.
                    980:  * 
                    981:  * Case four: SrvrDemo.exe -Embedding filename
                    982:  *   fEmbedding = TRUE
                    983:  *   Load file.
                    984:  *   Call OleRegisterServerDoc.
                    985:  *   Do not show window until client requests it.
                    986:  *
                    987:  * 
                    988:  * LPSTR lpszLine - The Windows command line
                    989:  * int nCmdShow   - Parameter to WinMain
                    990:  * HWND hwndMain  - The application's main window
                    991:  * 
                    992:  * RETURNS: TRUE  if the command line was processed correctly.
                    993:  *          FALSE if a filename was specified which did not
                    994:  *                contain a proper document.
                    995:  *
                    996:  * CUSTOMIZATION: None.
                    997:  *
                    998:  */
                    999:  
                   1000: static BOOL ProcessCmdLine (LPSTR lpszLine, HWND hwndMain)
                   1001: {
                   1002:    CHAR     szBuf[cchFilenameMax];
                   1003:    BOOL     fEmbedding = FALSE;  // Is "-Embedding" on the command line?
                   1004:    INT      i=0;
                   1005:    OFSTRUCT of;
                   1006:         
                   1007:    if (!*lpszLine)    // No filename or options, so start a fresh document.
                   1008:    {
                   1009:       return CreateUntitledDoc(SW_SHOWNORMAL);
                   1010:    }
                   1011:     
                   1012:    SkipBlanks (&lpszLine);
                   1013: 
                   1014:    // Check for "-Embedding" or "/Embedding" and set fEmbedding.
                   1015:    if(*lpszLine == '-' || *lpszLine == '/')
                   1016:    {
                   1017:       lpszLine++;
                   1018:       GetWord (&lpszLine, szBuf);
                   1019:       fEmbedding = !lstrcmp(szBuf, szEmbeddingFlag);
                   1020:    }
                   1021: 
                   1022:    SkipBlanks (&lpszLine);
                   1023: 
                   1024:    if (*lpszLine) // if there is a filename
                   1025:    {
                   1026:       // Put filename into szBuf.
                   1027:       GetWord (&lpszLine, szBuf);
                   1028: 
                   1029:       if (-1 == OpenFile(szBuf, &of, OF_READ | OF_EXIST))
                   1030:       {
                   1031:          // File not found
                   1032:          if (fEmbedding)
                   1033:             return FALSE;       
                   1034:          else
                   1035:          {
                   1036:             CHAR sz[100];
                   1037:             wsprintf (sz, "File %s not found.", (LPSTR) szBuf);
                   1038:             ErrorBox (sz);
                   1039:             return CreateUntitledDoc(SW_SHOWNORMAL);
                   1040:          }
                   1041:       }
                   1042: 
                   1043:       if (!CreateDocFromFile (szBuf, NULL, doctypeFromFile))
                   1044:       {
                   1045:          // File not in proper format.
                   1046:          if (fEmbedding)
                   1047:             return FALSE;       
                   1048:          else
                   1049:          {
                   1050:             CHAR sz[100];
                   1051:             wsprintf (sz, "File %s not in proper format.", (LPSTR) szBuf);
                   1052:             ErrorBox (sz);
                   1053:             return CreateUntitledDoc(SW_SHOWNORMAL);
                   1054:          }
                   1055:       }
                   1056:    }
                   1057: 
                   1058:    if (fEmbedding)
                   1059:    {
                   1060:       /* Do not show window until told to do so by client. */
                   1061:       ShowWindow(hwndMain, SW_HIDE);
                   1062:    }
                   1063:    else
                   1064:    {
                   1065:       ShowWindow(hwndMain, SW_SHOWNORMAL);
                   1066:       UpdateWindow(hwndMain);
                   1067:    }
                   1068:    return TRUE;
                   1069: }
                   1070: 
                   1071: 
                   1072: 
                   1073: /* SaveDimensions
                   1074:  * --------------
                   1075:  *
                   1076:  * Save the dimensions of the main window in a private profile file.
                   1077:  *
                   1078:  * CUSTOMIZATION: This function may be removed.  If you wish to support
                   1079:  *                intelligent window placement, then the only necessary
                   1080:  *                change is to change the string "SrvrDemo.Ini" to a filename
                   1081:  *                appropriate for your application.
                   1082:  */
                   1083: static VOID SaveDimensions (VOID)
                   1084: {
                   1085:    if ((dimsCurrent.nX != dimsSaved.nX) || 
                   1086:          (dimsCurrent.nY != dimsSaved.nY) ||
                   1087:          (dimsCurrent.nWidth != dimsSaved.nWidth) || 
                   1088:          (dimsCurrent.nHeight != dimsSaved.nHeight) )
                   1089:    {
                   1090:          // Save current window dimensions to private profile.
                   1091:          CHAR szBuf[7];
                   1092:          wsprintf (szBuf, "%d", dimsCurrent.nX);
                   1093:          WritePrivateProfileString
                   1094:          (szAppName, "x", szBuf, "SrvrDemo.Ini");
                   1095:          wsprintf (szBuf, "%d", dimsCurrent.nY);
                   1096:          WritePrivateProfileString
                   1097:          (szAppName, "y", szBuf, "SrvrDemo.Ini");
                   1098:          wsprintf (szBuf, "%d", dimsCurrent.nWidth);
                   1099:          WritePrivateProfileString
                   1100:          (szAppName, "w", szBuf, "SrvrDemo.Ini");
                   1101:          wsprintf (szBuf, "%d", dimsCurrent.nHeight);
                   1102:          WritePrivateProfileString
                   1103:          (szAppName, "h", szBuf, "SrvrDemo.Ini");
                   1104:    }
                   1105: }
                   1106: 
                   1107: 
                   1108: 
                   1109: /* SelectedObject
                   1110:  * --------------
                   1111:  *
                   1112:  * Return a pointer to the currently selected object.
                   1113:  *
                   1114:  * CUSTOMIZATION: What a "selected object" is will vary from application
                   1115:  *                to application.  You may find it useful to have a function
                   1116:  *                like this.  In your application it may be necessary to
                   1117:  *                actually create an OBJ structure based on what data the
                   1118:  *                user has selected from the document (by highlighting some
                   1119:  *                text for example).  
                   1120:  *
                   1121:  */
                   1122: LPOBJ SelectedObject (VOID)
                   1123: {
                   1124:    return HwndToLpobj (SelectedObjectWindow());
                   1125: }
                   1126:  
                   1127: 
                   1128: 
                   1129: 
                   1130: /* SelectedObjectWindow
                   1131:  * --------------------
                   1132:  *
                   1133:  * Return a handle to the window for the currently selected object.
                   1134:  * The GetWindow calls returns a handle to the main window's first child,
                   1135:  * which is the selected object's window.  
                   1136:  *
                   1137:  * CUSTOMIZATION: Server Demo specific
                   1138:  *
                   1139:  */
                   1140: HWND SelectedObjectWindow (VOID)
                   1141: {
                   1142:    return GetWindow (hwndMain, GW_CHILD);
                   1143: }
                   1144: 
                   1145: 
                   1146: 
                   1147: /* SetHiMetricFields
                   1148:  * -----------------
                   1149:  *
                   1150:  * Adjust the nHiMetricWidth and nHiMetricHeight fields of a NATIVE structure
                   1151:  * so that they are equivalent to the nWidth and nHeight fields.
                   1152:  * The negative sign in the last line is necessary because the positive 
                   1153:  * y direction is toward the top of the screen in MM_HIMETRIC mode.
                   1154:  *
                   1155:  * LPOBJ lpobj - Pointer to the object whose native data will be adjusted
                   1156:  *
                   1157:  * CUSTOMIZATION: Server Demo specific, although you may need a function like
                   1158:  *                this if you keep track of the size of an object, and an 
                   1159:  *                object handler needs to know the object's size in 
                   1160:  *                HiMetric units.
                   1161:  *
                   1162:  *
                   1163:  */
                   1164: VOID SetHiMetricFields (LPOBJ lpobj)
                   1165: {
                   1166:    POINT pt;
                   1167:    
                   1168:    pt.x = lpobj->native.nWidth;
                   1169:    pt.y = lpobj->native.nHeight;
1.1.1.2 ! root     1170:    DeviceToHiMetric ( &pt);
1.1       root     1171:    lpobj->native.nHiMetricWidth  = pt.x;
                   1172:    lpobj->native.nHiMetricHeight = pt.y;
                   1173: }
                   1174: 
                   1175: 
                   1176: 
                   1177: /* SkipBlanks
                   1178:  * ----------
                   1179:  * 
                   1180:  * LPSTR *plpsz - Pointer to a pointer to a character
                   1181:  *
                   1182:  * Increment *plpsz past any blanks in the character string.
                   1183:  * This function is used in ProcessCmdLine.
                   1184:  *
                   1185:  */
                   1186: static VOID SkipBlanks (LPSTR *plpsz)
                   1187: {
                   1188:    while (**plpsz && **plpsz == ' ')
                   1189:       (*plpsz)++;
                   1190: }
                   1191: 
                   1192: 
                   1193: 
                   1194: /* UpdateObjMenus
                   1195:  * ---------------
                   1196:  *
                   1197:  * Grey or Ungrey menu items depending on the existence of at least one 
                   1198:  * object in the document.
                   1199:  *
                   1200:  * CUSTOMIZATION: Server Demo specific
                   1201:  *
                   1202:  */
                   1203: static VOID UpdateObjMenus (VOID)
                   1204: {
                   1205:     static BOOL fObjMenusEnabled = TRUE;
                   1206:     BOOL        fOneObjExists; // Does at least one object exist?
                   1207:     WORD        wEnable;
                   1208:     HMENU       hMenu;
                   1209: 
                   1210:     fOneObjExists = (SelectedObjectWindow() != NULL);
                   1211:     if (fOneObjExists == fObjMenusEnabled)
                   1212:     {
                   1213:          // Nothing has changed.
                   1214:          return;
                   1215:     }
                   1216: 
                   1217:     wEnable = (WORD)(fOneObjExists ? MF_ENABLED : MF_GRAYED);
                   1218: 
                   1219:     hMenu = GetMenu(hwndMain);
                   1220:     EnableMenuItem(hMenu, menuposColor, MF_BYPOSITION | wEnable);
                   1221: 
                   1222:     hMenu = GetSubMenu(GetMenu(hwndMain), menuposFile);
                   1223:     EnableMenuItem(hMenu, IDM_SAVE,   MF_BYCOMMAND | wEnable);
                   1224:     EnableMenuItem(hMenu, IDM_SAVEAS, MF_BYCOMMAND | wEnable);
                   1225: 
                   1226:     hMenu = GetSubMenu(GetMenu(hwndMain), menuposEdit);
                   1227:     EnableMenuItem(hMenu, IDM_CUT,     MF_BYCOMMAND | wEnable);
                   1228:     EnableMenuItem(hMenu, IDM_COPY,    MF_BYCOMMAND | wEnable);
                   1229:     EnableMenuItem(hMenu, IDM_DELETE,  MF_BYCOMMAND | wEnable);
                   1230: 
                   1231:     hMenu = GetSubMenu(GetMenu(hwndMain), menuposObject);
                   1232:     EnableMenuItem(hMenu, IDM_NEXTOBJ, MF_BYCOMMAND | wEnable);
                   1233: 
                   1234:     DrawMenuBar (hwndMain);
                   1235:     fObjMenusEnabled = fOneObjExists;
                   1236: }
                   1237: 
                   1238: 
                   1239: 
                   1240: /* Wait
                   1241:  * ----
                   1242:  *
                   1243:  * Dispatch messages until the given flag is set to FALSE.
                   1244:  * One use of this function is to wait until a Release method is called
                   1245:  * after a function has returned OLE_WAIT_FOR_RELEASE.
                   1246:  *
                   1247:  * BOOL *pf - Pointer to the flag being waited on.
                   1248:  *
                   1249:  * CUSTOMIZATION: The use of OleUnblockServer is for illustration only.
                   1250:  *                Since Server Demo does not call OleBlockServer, there 
                   1251:  *                will never be any messages in the OLE queue.
                   1252:  *
                   1253:  */
                   1254: VOID Wait (BOOL *pf)
                   1255: {
                   1256:    MSG msg;
                   1257:    BOOL fMoreMsgs = FALSE;
                   1258: 
                   1259:    *pf = TRUE;
                   1260:    while (*pf==TRUE)
                   1261:    {
                   1262:       OleUnblockServer (srvrMain.lhsrvr, &fMoreMsgs);
                   1263:       if (!fMoreMsgs)
                   1264:       // if there are no more messages in the OLE queue, go to system queue
                   1265:       {
                   1266:          if (GetMessage (&msg, NULL, NULL, NULL))
                   1267:          {
                   1268:             TranslateMessage (&msg);
                   1269:             DispatchMessage (&msg);
                   1270:          }
                   1271:       }
                   1272:    }
                   1273: }
                   1274: 
                   1275: static BOOL FailedUpdate(HWND hwnd)
                   1276: {
                   1277: 
                   1278:   return(DialogBox(hInst, "FailedUpdate", hwnd, (DLGPROC)fnFailedUpdate));
                   1279: 
                   1280: }
                   1281: 
1.1.1.2 ! root     1282: BOOL  APIENTRY fnFailedUpdate (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root     1283: {
                   1284: 
                   1285:    switch (message) 
                   1286:    {
                   1287:       case WM_COMMAND:
                   1288:       {
                   1289:          WORD wID = LOWORD(wParam);
                   1290: 
                   1291:          switch (wID) 
                   1292:          {
                   1293:                case IDCANCEL:
                   1294:                case IDD_CONTINUEEDIT:
                   1295:                    EndDialog(hDlg, TRUE);
                   1296:                    break;
                   1297: 
                   1298:                case IDD_UPDATEEXIT:
                   1299:                    EndDialog(hDlg, FALSE);
                   1300:                    break;
                   1301: 
                   1302:                default:
                   1303:                    break;
                   1304:          }
                   1305:          break;
                   1306:        }
                   1307: 
                   1308:        case WM_INITDIALOG:
                   1309:        {
                   1310:           CHAR szMsg[200];
                   1311: 
                   1312:           szMsg[0] = NULL;
                   1313: 
                   1314:           wsprintf(
                   1315:                szMsg, 
                   1316:                "This %s document can only be updated when you exit %s.",
                   1317:                (LPSTR) szClient,
                   1318:                (LPSTR) szAppName
                   1319:           );
                   1320: 
                   1321:           SetDlgItemText(hDlg, IDD_TEXT, szMsg);
                   1322:           return TRUE; 
                   1323:        }
                   1324:        
                   1325:       default:
                   1326:            break;
                   1327:    }
                   1328: 
                   1329:    return FALSE;
                   1330: }
1.1.1.2 ! root     1331: 
        !          1332: 
        !          1333: 
        !          1334: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.