|
|
1.1 ! root 1: /* ! 2: * utility.c - general purpose utility routines ! 3: * ! 4: * Created by Microsoft Corporation. ! 5: * (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved ! 6: * ! 7: */ ! 8: ! 9: //*** INCLUDES **** ! 10: ! 11: #include <windows.h> ! 12: #include <ole.h> ! 13: ! 14: #include "global.h" ! 15: #include "demorc.h" ! 16: #include "utility.h" ! 17: #include "object.h" ! 18: #include "dialog.h" ! 19: ! 20: static INT iTimerID = 0; ! 21: static APPITEMPTR lpaItemHold; ! 22: ! 23: ! 24: /**************************************************************************** ! 25: * ErrorMessage() ! 26: * ! 27: * Display a message box containing the specified string from the table. ! 28: * ! 29: * id WORD - Index into string table. ! 30: ***************************************************************************/ ! 31: ! 32: VOID FAR ErrorMessage( //* ENTRY: ! 33: DWORD id //* message ID ! 34: ){ //* LOCAL: ! 35: CHAR sz[CBMESSAGEMAX]; //* string ! 36: HWND hwnd; //* parent window handle ! 37: ! 38: if (IsWindow(hwndProp)) ! 39: hwnd = hwndProp; ! 40: else if (IsWindow(hwndFrame)) ! 41: hwnd = hwndFrame; ! 42: else ! 43: return; ! 44: ! 45: LoadString(hInst, id, sz, CBMESSAGEMAX); ! 46: MessageBox(hwnd, sz, szAppName, MB_OK | MB_ICONEXCLAMATION); ! 47: ! 48: } ! 49: ! 50: ! 51: /**************************************************************************** ! 52: * Hourglass() ! 53: * ! 54: * Put up or takes down the hourglass cursor as needed. ! 55: * ! 56: * int bToggle - TRUE turns the hour glass on ! 57: * HG_OFF turn it off ! 58: ***************************************************************************/ ! 59: ! 60: VOID FAR Hourglass( //* ENTRY: ! 61: BOOL bOn //* hourglass on/off ! 62: ){ //* LOCAL: ! 63: static HCURSOR hcurWait = NULL; //* hourglass cursor ! 64: static HCURSOR hcurSaved; //* old cursor ! 65: static iCount = 0; ! 66: ! 67: ! 68: if (bOn) ! 69: { ! 70: iCount++; ! 71: if (!hcurWait) ! 72: hcurWait = LoadCursor(NULL, IDC_WAIT); ! 73: if (!hcurSaved) ! 74: hcurSaved = SetCursor(hcurWait); ! 75: } ! 76: else if (!bOn) ! 77: { ! 78: if (--iCount < 0 ) ! 79: iCount = 0; ! 80: else if (!iCount) ! 81: { ! 82: SetCursor(hcurSaved); ! 83: hcurSaved = NULL; ! 84: } ! 85: } ! 86: ! 87: } ! 88: ! 89: /*************************************************************************** ! 90: * WaitForObject() ! 91: * ! 92: * Dispatch messagee until the specified object is not busy. ! 93: * This allows asynchronous processing to occur. ! 94: * ! 95: * lpObject LPOLEOBJECT - pointer to object ! 96: **************************************************************************/ ! 97: ! 98: void FAR WaitForObject( //* ENTRY: ! 99: APPITEMPTR paItem //* pointer to OLE object ! 100: ){ //* LOCAL ! 101: BOOL bTimerOn = FALSE; ! 102: ! 103: while (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY) ! 104: { ! 105: lpaItemHold = paItem; ! 106: if (!bTimerOn) ! 107: bTimerOn = ToggleBlockTimer(TRUE);//* set timer ! 108: ProcessMessage(hwndFrame, hAccTable); ! 109: } ! 110: ! 111: if (bTimerOn) ! 112: ToggleBlockTimer(FALSE);//* toggle timer off ! 113: } ! 114: ! 115: /*************************************************************************** ! 116: * WaitForAllObjects() ! 117: * ! 118: * Wait for all asynchronous operations to complete. ! 119: **************************************************************************/ ! 120: ! 121: VOID FAR WaitForAllObjects(VOID) ! 122: { ! 123: BOOL bTimerOn = FALSE; ! 124: ! 125: while (cOleWait) ! 126: { ! 127: if (!bTimerOn) ! 128: bTimerOn = ToggleBlockTimer(TRUE);//* set timer ! 129: ! 130: ProcessMessage(hwndFrame, hAccTable) ; ! 131: } ! 132: ! 133: if (bTimerOn) ! 134: ToggleBlockTimer(FALSE);//* toggle timer off ! 135: ! 136: } ! 137: ! 138: /**************************************************************************** ! 139: * ProcessMessage() ! 140: * ! 141: * Obtain and dispatch a message. Used when in a message dispatch loop. ! 142: * ! 143: * Returns BOOL - TRUE if message other than WM_QUIT retrieved ! 144: * FALSE if WM_QUIT retrieved. ! 145: ***************************************************************************/ ! 146: ! 147: BOOL FAR ProcessMessage( //* ENTRY: ! 148: HWND hwndFrame, //* main window handle ! 149: HANDLE hAccTable //* accelerator table handle ! 150: ){ //* LOCAL: ! 151: BOOL fReturn; //* return value ! 152: MSG msg; //* message ! 153: ! 154: if (fReturn = GetMessage(&msg, NULL, NULL, NULL)) ! 155: { ! 156: if (cOleWait || !TranslateAccelerator(hwndFrame, hAccTable, &msg)) ! 157: { ! 158: TranslateMessage(&msg); ! 159: DispatchMessage(&msg); ! 160: } ! 161: } ! 162: return fReturn; ! 163: ! 164: } ! 165: ! 166: ! 167: /**************************************************************************** ! 168: * Dirty() ! 169: * ! 170: * Keep track of weather modifications have been made ! 171: * to the document or not. ! 172: * ! 173: * iAction - action type: ! 174: * DOC_CLEAN set document clean flag true ! 175: * DOC_DIRTY the opposite ! 176: * DOC_UNDIRTY undo one dirty op ! 177: * DOC_QUERY return present state ! 178: * ! 179: * Returs int - present value of fDirty; 0 is clean. ! 180: ***************************************************************************/ ! 181: ! 182: INT FAR Dirty( //* ENTRY: ! 183: INT iAction //* see above comment ! 184: ){ //* LOCAL: ! 185: static INT iDirty = 0; //* dirty state >0 is dirty ! 186: ! 187: switch (iAction) ! 188: { ! 189: case DOC_CLEAN: ! 190: iDirty = 0; ! 191: break; ! 192: case DOC_DIRTY: ! 193: iDirty++; ! 194: break; ! 195: case DOC_UNDIRTY: ! 196: iDirty--; ! 197: break; ! 198: case DOC_QUERY: ! 199: break; ! 200: } ! 201: return(iDirty); ! 202: ! 203: } ! 204: ! 205: /*************************************************************************** ! 206: * ObjectsBusy() ! 207: * ! 208: * This function enumerates the OLE objects in the current document ! 209: * and displays a message box stating whether an object is busy. ! 210: * This function calls the DisplayBusyMessage() function which ! 211: * performs most of the work. This function is only used by the macro ! 212: * BUSY_CHECK(), defined in object.h. ! 213: * ! 214: * fSelectionOnly BOOL -NOT USED? ! 215: * ! 216: * BOOL - TRUE if one or more objects found to be busy ! 217: * FALSE otherwise ! 218: * ! 219: ***************************************************************************/ ! 220: ! 221: BOOL FAR ObjectsBusy () ! 222: { ! 223: APPITEMPTR pItem; ! 224: ! 225: if (iTimerID) ! 226: { ! 227: RetryMessage(NULL,RD_CANCEL); ! 228: return TRUE; ! 229: } ! 230: ! 231: for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) ! 232: if (DisplayBusyMessage(pItem)) ! 233: return TRUE; ! 234: ! 235: return FALSE; ! 236: ! 237: } ! 238: ! 239: /*************************************************************************** ! 240: * DisplayBusyMessage() ! 241: * ! 242: * This function determines if an object is busy and displays ! 243: * a message box stating this status. ! 244: * ! 245: * Returns BOOL - TRUE if object is busy ! 246: **************************************************************************/ ! 247: ! 248: BOOL FAR DisplayBusyMessage ( //* ENTRY: ! 249: APPITEMPTR paItem //* application item pointer ! 250: ){ //* LOCAL: ! 251: ! 252: if (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY) ! 253: { ! 254: RetryMessage(paItem,RD_CANCEL); ! 255: return TRUE; ! 256: } ! 257: return FALSE; ! 258: ! 259: } ! 260: ! 261: /*************************************************************************** ! 262: * CreateNewUniqueName() ! 263: * ! 264: * Create a string name unique to this document. This is done by using the ! 265: * prefix string("OleDemo #") and appending a counter to the end of the ! 266: * prefix string. The counter is incremented whenever a new object is added. ! 267: * String will be 14 bytes long. ! 268: * ! 269: * Return LPSTR - pointer to unique object name. ! 270: ***************************************************************************/ ! 271: ! 272: LPSTR FAR CreateNewUniqueName( //* ENTRY: ! 273: LPSTR lpstr //* destination pointer ! 274: ){ ! 275: ! 276: wsprintf( lpstr, "%s%04d", OBJPREFIX, iObjectNumber++ ); ! 277: return( lpstr ); ! 278: ! 279: } ! 280: ! 281: /*************************************************************************** ! 282: * ValidateName() ! 283: * ! 284: * This function ensures that the given object name is valid and unique. ! 285: * ! 286: * Returns: BOOL - TRUE if object name valid ! 287: **************************************************************************/ ! 288: ! 289: BOOL FAR ValidateName( //* ENTRY: ! 290: LPSTR lpstr //* pointer to object name ! 291: ){ //* LOCAL: ! 292: LPSTR lp; //* worker string ! 293: INT n; ! 294: //* check for "OleDemo #" prefix ! 295: lp = OBJPREFIX; ! 296: ! 297: while( *lp ) ! 298: { ! 299: if( *lpstr != *lp ) ! 300: return( FALSE ); ! 301: ! 302: lpstr++; lp++; ! 303: } ! 304: //* convert string number to int ! 305: for (n = 0 ; *lpstr ; n = n*10 + (*lpstr - '0'),lpstr++); ! 306: ! 307: if( n > 9999 ) //* 9999 is largest legal number ! 308: return FALSE; ! 309: ! 310: if( iObjectNumber <= n) //* Make count > than any current ! 311: iObjectNumber = n + 1; //* object to ensure uniqueness ! 312: ! 313: return TRUE; ! 314: } ! 315: ! 316: /*************************************************************************** ! 317: * FreeAppItem() ! 318: * ! 319: * Free application item structure and destroy the associated structure. ! 320: **************************************************************************/ ! 321: ! 322: VOID FAR FreeAppItem( //* ENTRY: ! 323: APPITEMPTR pItem //* pointer to application item ! 324: ){ //* LOCAL: ! 325: HANDLE hWork; //* handle used to free ! 326: ! 327: if (pItem) ! 328: { //* destroy the window ! 329: if (pItem->hwnd) ! 330: DestroyWindow(pItem->hwnd); ! 331: ! 332: hWork = LocalHandle((LPSTR)pItem);//* get handle from pointer ! 333: ! 334: if (pItem->aLinkName) ! 335: DeleteAtom(pItem->aLinkName); ! 336: ! 337: if (pItem->aServer) ! 338: DeleteAtom(pItem->aServer); ! 339: ! 340: LocalUnlock(hWork); ! 341: LocalFree(hWork); ! 342: } ! 343: ! 344: } ! 345: ! 346: /*************************************************************************** ! 347: * SizeOfLinkData() ! 348: * ! 349: * Find the size of a linkdata string. ! 350: **************************************************************************/ ! 351: ! 352: LONG FAR SizeOfLinkData( //* ENTRY: ! 353: LPSTR lpData //* pointer to link data ! 354: ){ //* LOCAL: ! 355: LONG lSize; //* total size ! 356: ! 357: lSize = (LONG)lstrlen(lpData)+1; //* get size of classname ! 358: lSize += (LONG)lstrlen(lpData+lSize)+1; //* get size of doc. ! 359: lSize += (LONG)lstrlen(lpData+lSize)+2;//* get size of item ! 360: return lSize; ! 361: ! 362: } ! 363: ! 364: /**************************************************************************** ! 365: * ShowDoc() ! 366: * ! 367: * Display all the child windows associated with a document, or make all the ! 368: * child windows hidden. ! 369: ***************************************************************************/ ! 370: ! 371: VOID FAR ShowDoc( //* ENTRY: ! 372: LHCLIENTDOC lhcDoc, //* document handle ! 373: INT iShow //* show/hide ! 374: ){ //* LOCAL: ! 375: APPITEMPTR pItem; //* application item pointer ! 376: APPITEMPTR pItemTop = NULL; ! 377: ! 378: for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) ! 379: { ! 380: if (pItem->lhcDoc == lhcDoc) ! 381: { ! 382: if (!pItemTop) ! 383: pItemTop = pItem; ! 384: ShowWindow(pItem->hwnd,(iShow ? SW_SHOW : SW_HIDE)); ! 385: pItem->fVisible = (BOOL)iShow; ! 386: } ! 387: } ! 388: ! 389: if (pItemTop) ! 390: SetTopItem(pItemTop); ! 391: ! 392: } ! 393: ! 394: /**************************************************************************** ! 395: * GetNextActiveItem() ! 396: * ! 397: * Returns HWND - the next visible window. ! 398: ***************************************************************************/ ! 399: ! 400: APPITEMPTR FAR GetNextActiveItem() ! 401: { //* LOCAL: ! 402: APPITEMPTR pItem; //* application item pointer ! 403: ! 404: for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) ! 405: if (pItem->fVisible) ! 406: break; ! 407: ! 408: return pItem; ! 409: ! 410: } ! 411: ! 412: /**************************************************************************** ! 413: * GetTopItem() ! 414: ***************************************************************************/ ! 415: ! 416: APPITEMPTR FAR GetTopItem() ! 417: { ! 418: HWND hwnd; ! 419: ! 420: if (hwnd = GetTopWindow(hwndFrame)) ! 421: return ((APPITEMPTR)GetWindowLong(hwnd,0)); ! 422: else ! 423: return NULL; ! 424: ! 425: } ! 426: /**************************************************************************** ! 427: * GetNextItem() ! 428: ***************************************************************************/ ! 429: ! 430: APPITEMPTR FAR GetNextItem( //* ENTRY: ! 431: APPITEMPTR pItem //* application item pointer ! 432: ){ //* LOCAL: ! 433: HWND hwnd; //* next item window handle ! 434: ! 435: if (hwnd = GetNextWindow(pItem->hwnd, GW_HWNDNEXT)) ! 436: return((APPITEMPTR)GetWindowLong(hwnd,0)); ! 437: else ! 438: return NULL; ! 439: ! 440: } ! 441: ! 442: /**************************************************************************** ! 443: * SetTopItem() ! 444: ***************************************************************************/ ! 445: ! 446: VOID FAR SetTopItem( ! 447: APPITEMPTR pItem ! 448: ){ ! 449: APPITEMPTR pLastItem; ! 450: ! 451: pLastItem = GetTopItem(); ! 452: if (pLastItem && pLastItem != pItem) ! 453: SendMessage(pLastItem->hwnd,WM_NCACTIVATE, 0, 0L); ! 454: ! 455: if (!pItem) ! 456: return; ! 457: ! 458: if (pItem->fVisible) ! 459: { ! 460: BringWindowToTop(pItem->hwnd); ! 461: SendMessage(pItem->hwnd,WM_NCACTIVATE, 1, 0L); ! 462: } ! 463: ! 464: } ! 465: ! 466: /*************************************************************************** ! 467: * ReallocLinkData() ! 468: * ! 469: * Reallocate link data in order to avoid creating lots and lots of global ! 470: * memory thunks. ! 471: **************************************************************************/ ! 472: ! 473: BOOL FAR ReallocLinkData( //* ENTRY: ! 474: APPITEMPTR pItem, //* application item pointer ! 475: LONG lSize //* new link data size ! 476: ){ //* LOCAL: ! 477: HANDLE handle; //* temporary memory handle ! 478: ! 479: handle = GlobalHandle(pItem->lpLinkData); ! 480: GlobalUnlock(handle); ! 481: ! 482: if (!(pItem->lpLinkData = GlobalLock(GlobalReAlloc(handle, lSize, NULL)))) ! 483: { ! 484: ErrorMessage(E_FAILED_TO_ALLOC); ! 485: return FALSE; ! 486: } ! 487: ! 488: return TRUE; ! 489: ! 490: } ! 491: ! 492: /*************************************************************************** ! 493: * AllocLinkData() ! 494: * ! 495: * Allocate link data space. ! 496: **************************************************************************/ ! 497: ! 498: BOOL FAR AllocLinkData( //* ENTRY: ! 499: APPITEMPTR pItem, //* application item pointer ! 500: LONG lSize //* link data size ! 501: ){ ! 502: ! 503: if (!(pItem->lpLinkData = GlobalLock( ! 504: GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT ,lSize) ! 505: ))) ! 506: { ! 507: ErrorMessage(E_FAILED_TO_ALLOC); ! 508: return FALSE; ! 509: } ! 510: ! 511: return TRUE; ! 512: } ! 513: ! 514: /*************************************************************************** ! 515: * FreeLinkData() ! 516: * ! 517: * Free the space associated with a linkdata pointer. ! 518: **************************************************************************/ ! 519: ! 520: VOID FAR FreeLinkData( //* ENTRY: ! 521: LPSTR lpLinkData //* pointer to linkdata ! 522: ){ //* LOCAL: ! 523: HANDLE handle; //* temporary memory handle ! 524: ! 525: if (lpLinkData) ! 526: { ! 527: handle = GlobalHandle(lpLinkData); ! 528: GlobalUnlock(handle); ! 529: GlobalFree(handle); ! 530: } ! 531: } ! 532: ! 533: /**************************************************************************** ! 534: * ShowNewWindow() ! 535: * ! 536: * Show a new application item window. ! 537: ***************************************************************************/ ! 538: ! 539: VOID FAR ShowNewWindow( //* ENTRY: ! 540: APPITEMPTR pItem ! 541: ){ ! 542: ! 543: if (pItem->fVisible) ! 544: { ! 545: pItem->fNew = TRUE; ! 546: SetTopItem(pItem); ! 547: ShowWindow(pItem->hwnd,SW_SHOW); ! 548: } ! 549: else ! 550: ObjDelete(pItem,OLE_OBJ_DELETE); ! 551: ! 552: } ! 553: ! 554: /**************************************************************************** ! 555: * UnqualifyPath() ! 556: * ! 557: * return pointer to unqualified path name. ! 558: ***************************************************************************/ ! 559: ! 560: PSTR FAR UnqualifyPath(PSTR pPath) ! 561: { ! 562: PSTR pReturn; ! 563: ! 564: for (pReturn = pPath; *pPath; pPath++) ! 565: if (*pPath == ':' || *pPath == '\\') ! 566: pReturn = pPath+1; ! 567: ! 568: return pReturn; ! 569: ! 570: } ! 571: ! 572: /**************************************************************************** ! 573: * ToggleBlockTimer() ! 574: * ! 575: * Toggle a timer used to check for blocked servers. ! 576: ***************************************************************************/ ! 577: ! 578: BOOL FAR ToggleBlockTimer(BOOL bSet) ! 579: { ! 580: if (bSet && !iTimerID) ! 581: { ! 582: if (iTimerID = SetTimer(hwndFrame,1, 3000, (TIMERPROC)fnTimerBlockProc)) ! 583: return TRUE; ! 584: } ! 585: else if (iTimerID) ! 586: { ! 587: KillTimer(hwndFrame,1); ! 588: iTimerID = 0; ! 589: return TRUE; ! 590: } ! 591: ! 592: return FALSE; ! 593: } ! 594: ! 595: /**************************************************************************** ! 596: * fnTimerBlockProc() ! 597: * ! 598: * Timer callback procedure ! 599: ***************************************************************************/ ! 600: ! 601: VOID FAR PASCAL fnTimerBlockProc( //* ENTRY: ! 602: HWND hWnd, ! 603: UINT wMsg, ! 604: UINT iTimerID, ! 605: DWORD dwTime ! 606: ){ ! 607: ! 608: if (!hRetry) ! 609: RetryMessage(lpaItemHold, RD_RETRY | RD_CANCEL); ! 610: ! 611: } ! 612: ! 613:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.