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

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

unix.superglobalmegacorp.com

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