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

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

unix.superglobalmegacorp.com

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