|
|
/*
* utility.c - general purpose utility routines * * Created by Microsoft Corporation. * (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved * */
//*** INCLUDES ****
#include <windows.h>
#include <ole.h>
#include "global.h"
#include "demorc.h"
#include "utility.h"
#include "object.h"
#include "dialog.h"
static INT iTimerID = 0; static APPITEMPTR lpaItemHold;
/****************************************************************************
* ErrorMessage() * * Display a message box containing the specified string from the table. * * id WORD - Index into string table. ***************************************************************************/
VOID FAR ErrorMessage( //* ENTRY:
DWORD id //* message ID
){ //* LOCAL:
CHAR sz[CBMESSAGEMAX]; //* string
HWND hwnd; //* parent window handle
if (IsWindow(hwndProp)) hwnd = hwndProp; else if (IsWindow(hwndFrame)) hwnd = hwndFrame; else return;
LoadString(hInst, id, sz, CBMESSAGEMAX); MessageBox(hwnd, sz, szAppName, MB_OK | MB_ICONEXCLAMATION);
}
/****************************************************************************
* Hourglass() * * Put up or takes down the hourglass cursor as needed. * * int bToggle - TRUE turns the hour glass on * HG_OFF turn it off ***************************************************************************/
VOID FAR Hourglass( //* ENTRY:
BOOL bOn //* hourglass on/off
){ //* LOCAL:
static HCURSOR hcurWait = NULL; //* hourglass cursor
static HCURSOR hcurSaved; //* old cursor
static iCount = 0;
if (bOn) { iCount++; if (!hcurWait) hcurWait = LoadCursor(NULL, IDC_WAIT); if (!hcurSaved) hcurSaved = SetCursor(hcurWait); } else if (!bOn) { if (--iCount < 0 ) iCount = 0; else if (!iCount) { SetCursor(hcurSaved); hcurSaved = NULL; } }
}
/***************************************************************************
* WaitForObject() * * Dispatch messagee until the specified object is not busy. * This allows asynchronous processing to occur. * * lpObject LPOLEOBJECT - pointer to object **************************************************************************/
void FAR WaitForObject( //* ENTRY:
APPITEMPTR paItem //* pointer to OLE object
){ //* LOCAL
BOOL bTimerOn = FALSE;
while (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY) { lpaItemHold = paItem; if (!bTimerOn) bTimerOn = ToggleBlockTimer(TRUE);//* set timer
ProcessMessage(hwndFrame, hAccTable); }
if (bTimerOn) ToggleBlockTimer(FALSE);//* toggle timer off
}
/***************************************************************************
* WaitForAllObjects() * * Wait for all asynchronous operations to complete. **************************************************************************/
VOID FAR WaitForAllObjects(VOID) { BOOL bTimerOn = FALSE;
while (cOleWait) { if (!bTimerOn) bTimerOn = ToggleBlockTimer(TRUE);//* set timer
ProcessMessage(hwndFrame, hAccTable) ; }
if (bTimerOn) ToggleBlockTimer(FALSE);//* toggle timer off
}
/****************************************************************************
* ProcessMessage() * * Obtain and dispatch a message. Used when in a message dispatch loop. * * Returns BOOL - TRUE if message other than WM_QUIT retrieved * FALSE if WM_QUIT retrieved. ***************************************************************************/
BOOL FAR ProcessMessage( //* ENTRY:
HWND hwndFrame, //* main window handle
HANDLE hAccTable //* accelerator table handle
){ //* LOCAL:
BOOL fReturn; //* return value
MSG msg; //* message
if (fReturn = GetMessage(&msg, NULL, 0, 0)) { if (cOleWait || !TranslateAccelerator(hwndFrame, hAccTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return fReturn;
}
/****************************************************************************
* Dirty() * * Keep track of weather modifications have been made * to the document or not. * * iAction - action type: * DOC_CLEAN set document clean flag true * DOC_DIRTY the opposite * DOC_UNDIRTY undo one dirty op * DOC_QUERY return present state * * Returs int - present value of fDirty; 0 is clean. ***************************************************************************/
INT FAR Dirty( //* ENTRY:
INT iAction //* see above comment
){ //* LOCAL:
static INT iDirty = 0; //* dirty state >0 is dirty
switch (iAction) { case DOC_CLEAN: iDirty = 0; break; case DOC_DIRTY: iDirty++; break; case DOC_UNDIRTY: iDirty--; break; case DOC_QUERY: break; } return(iDirty);
}
/***************************************************************************
* ObjectsBusy() * * This function enumerates the OLE objects in the current document * and displays a message box stating whether an object is busy. * This function calls the DisplayBusyMessage() function which * performs most of the work. This function is only used by the macro * BUSY_CHECK(), defined in object.h. * * fSelectionOnly BOOL -NOT USED? * * BOOL - TRUE if one or more objects found to be busy * FALSE otherwise * ***************************************************************************/
BOOL FAR ObjectsBusy () { APPITEMPTR pItem;
if (iTimerID) { RetryMessage(NULL,RD_CANCEL); return TRUE; }
for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) if (DisplayBusyMessage(pItem)) return TRUE;
return FALSE;
}
/***************************************************************************
* DisplayBusyMessage() * * This function determines if an object is busy and displays * a message box stating this status. * * Returns BOOL - TRUE if object is busy **************************************************************************/
BOOL FAR DisplayBusyMessage ( //* ENTRY:
APPITEMPTR paItem //* application item pointer
){ //* LOCAL:
if (OleQueryReleaseStatus(paItem->lpObject) == OLE_BUSY) { RetryMessage(paItem,RD_CANCEL); return TRUE; } return FALSE;
}
/***************************************************************************
* CreateNewUniqueName() * * Create a string name unique to this document. This is done by using the * prefix string("OleDemo #") and appending a counter to the end of the * prefix string. The counter is incremented whenever a new object is added. * String will be 14 bytes long. * * Return LPSTR - pointer to unique object name. ***************************************************************************/
LPSTR FAR CreateNewUniqueName( //* ENTRY:
LPSTR lpstr //* destination pointer
){
wsprintf( lpstr, "%s%04d", OBJPREFIX, iObjectNumber++ ); return( lpstr );
}
/***************************************************************************
* ValidateName() * * This function ensures that the given object name is valid and unique. * * Returns: BOOL - TRUE if object name valid **************************************************************************/
BOOL FAR ValidateName( //* ENTRY:
LPSTR lpstr //* pointer to object name
){ //* LOCAL:
LPSTR lp; //* worker string
INT n; //* check for "OleDemo #" prefix
lp = OBJPREFIX;
while( *lp ) { if( *lpstr != *lp ) return( FALSE );
lpstr++; lp++; } //* convert string number to int
for (n = 0 ; *lpstr ; n = n*10 + (*lpstr - '0'),lpstr++);
if( n > 9999 ) //* 9999 is largest legal number
return FALSE;
if( iObjectNumber <= n) //* Make count > than any current
iObjectNumber = n + 1; //* object to ensure uniqueness
return TRUE; }
/***************************************************************************
* FreeAppItem() * * Free application item structure and destroy the associated structure. **************************************************************************/
VOID FAR FreeAppItem( //* ENTRY:
APPITEMPTR pItem //* pointer to application item
){ //* LOCAL:
HANDLE hWork; //* handle used to free
if (pItem) { //* destroy the window
if (pItem->hwnd) DestroyWindow(pItem->hwnd);
hWork = LocalHandle((LPSTR)pItem);//* get handle from pointer
if (pItem->aLinkName) DeleteAtom(pItem->aLinkName);
if (pItem->aServer) DeleteAtom(pItem->aServer);
LocalUnlock(hWork); LocalFree(hWork); }
}
/***************************************************************************
* SizeOfLinkData() * * Find the size of a linkdata string. **************************************************************************/
LONG FAR SizeOfLinkData( //* ENTRY:
LPSTR lpData //* pointer to link data
){ //* LOCAL:
LONG lSize; //* total size
lSize = (LONG)lstrlen(lpData)+1; //* get size of classname
lSize += (LONG)lstrlen(lpData+lSize)+1; //* get size of doc.
lSize += (LONG)lstrlen(lpData+lSize)+2;//* get size of item
return lSize;
}
/****************************************************************************
* ShowDoc() * * Display all the child windows associated with a document, or make all the * child windows hidden. ***************************************************************************/
VOID FAR ShowDoc( //* ENTRY:
LHCLIENTDOC lhcDoc, //* document handle
INT iShow //* show/hide
){ //* LOCAL:
APPITEMPTR pItem; //* application item pointer
APPITEMPTR pItemTop = NULL;
for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) { if (pItem->lhcDoc == lhcDoc) { if (!pItemTop) pItemTop = pItem; ShowWindow(pItem->hwnd,(iShow ? SW_SHOW : SW_HIDE)); pItem->fVisible = (BOOL)iShow; } } if (pItemTop) SetTopItem(pItemTop);
} /****************************************************************************
* GetNextActiveItem() * * Returns HWND - the next visible window. ***************************************************************************/
APPITEMPTR FAR GetNextActiveItem() { //* LOCAL:
APPITEMPTR pItem; //* application item pointer
for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem)) if (pItem->fVisible) break;
return pItem;
} /****************************************************************************
* GetTopItem() ***************************************************************************/
APPITEMPTR FAR GetTopItem() { HWND hwnd;
if (hwnd = GetTopWindow(hwndFrame)) return ((APPITEMPTR)GetWindowLong(hwnd,0)); else return NULL;
} /****************************************************************************
* GetNextItem() ***************************************************************************/
APPITEMPTR FAR GetNextItem( //* ENTRY:
APPITEMPTR pItem //* application item pointer
){ //* LOCAL:
HWND hwnd; //* next item window handle
if (hwnd = GetNextWindow(pItem->hwnd, GW_HWNDNEXT)) return((APPITEMPTR)GetWindowLong(hwnd,0)); else return NULL;
}
/****************************************************************************
* SetTopItem() ***************************************************************************/
VOID FAR SetTopItem( APPITEMPTR pItem ){ APPITEMPTR pLastItem;
pLastItem = GetTopItem(); if (pLastItem && pLastItem != pItem) SendMessage(pLastItem->hwnd,WM_NCACTIVATE, 0, 0L);
if (!pItem) return;
if (pItem->fVisible) { BringWindowToTop(pItem->hwnd); SendMessage(pItem->hwnd,WM_NCACTIVATE, 1, 0L); }
}
/***************************************************************************
* ReallocLinkData() * * Reallocate link data in order to avoid creating lots and lots of global * memory thunks. **************************************************************************/
BOOL FAR ReallocLinkData( //* ENTRY:
APPITEMPTR pItem, //* application item pointer
LONG lSize //* new link data size
){ //* LOCAL:
HANDLE handle; //* temporary memory handle
handle = GlobalHandle(pItem->lpLinkData); GlobalUnlock(handle);
if (!(pItem->lpLinkData = GlobalLock(GlobalReAlloc(handle, lSize, 0)))) { ErrorMessage(E_FAILED_TO_ALLOC); return FALSE; }
return TRUE;
}
/***************************************************************************
* AllocLinkData() * * Allocate link data space. **************************************************************************/
BOOL FAR AllocLinkData( //* ENTRY:
APPITEMPTR pItem, //* application item pointer
LONG lSize //* link data size
){
if (!(pItem->lpLinkData = GlobalLock( GlobalAlloc(GMEM_DDESHARE | GMEM_ZEROINIT ,lSize) ))) { ErrorMessage(E_FAILED_TO_ALLOC); return FALSE; }
return TRUE; }
/***************************************************************************
* FreeLinkData() * * Free the space associated with a linkdata pointer. **************************************************************************/
VOID FAR FreeLinkData( //* ENTRY:
LPSTR lpLinkData //* pointer to linkdata
){ //* LOCAL:
HANDLE handle; //* temporary memory handle
if (lpLinkData) { handle = GlobalHandle(lpLinkData); GlobalUnlock(handle); GlobalFree(handle); } }
/****************************************************************************
* ShowNewWindow() * * Show a new application item window. ***************************************************************************/
VOID FAR ShowNewWindow( //* ENTRY:
APPITEMPTR pItem ){
if (pItem->fVisible) { pItem->fNew = TRUE; SetTopItem(pItem); ShowWindow(pItem->hwnd,SW_SHOW); } else ObjDelete(pItem,OLE_OBJ_DELETE);
}
/****************************************************************************
* UnqualifyPath() * * return pointer to unqualified path name. ***************************************************************************/
PSTR FAR UnqualifyPath(PSTR pPath) { PSTR pReturn;
for (pReturn = pPath; *pPath; pPath++) if (*pPath == ':' || *pPath == '\\') pReturn = pPath+1;
return pReturn;
}
/****************************************************************************
* ToggleBlockTimer() * * Toggle a timer used to check for blocked servers. ***************************************************************************/
BOOL FAR ToggleBlockTimer(BOOL bSet) { if (bSet && !iTimerID) { if (iTimerID = SetTimer(hwndFrame,1, 3000, (TIMERPROC) fnTimerBlockProc)) return TRUE; } else if (iTimerID) { KillTimer(hwndFrame,1); iTimerID = 0; return TRUE; } return FALSE; }
/****************************************************************************
* fnTimerBlockProc() * * Timer callback procedure ***************************************************************************/
VOID CALLBACK fnTimerBlockProc( //* ENTRY:
HWND hWnd, UINT wMsg, UINT iTimerID, DWORD dwTime ){
if (!hRetry) RetryMessage(lpaItemHold, RD_RETRY | RD_CANCEL);
}
|