Annotation of mstools/ole20/samples/ole2ui/busy.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * BUSY.C
        !             3:  *
        !             4:  * Implements the OleUIBusy function which invokes the "Server Busy"
        !             5:  * dialog.
        !             6:  *
        !             7:  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
        !             8:  */
        !             9:  
        !            10: #define STRICT  1
        !            11: #include "ole2ui.h"
        !            12: #include "common.h"
        !            13: #include "utility.h"
        !            14: #include "busy.h" 
        !            15: #include <ctype.h> // for tolower() and toupper()
        !            16: 
        !            17: #ifndef WIN32
        !            18: #include <toolhelp.h>
        !            19: #endif
        !            20: 
        !            21: 
        !            22: /*
        !            23:  * OleUIBusy
        !            24:  *
        !            25:  * Purpose:
        !            26:  *  Invokes the standard OLE "Server Busy" dialog box which
        !            27:  *  notifies the user that the server application is not receiving
        !            28:  *  messages.  The dialog then asks the user to either cancel
        !            29:  *  the operation, switch to the task which is blocked, or continue
        !            30:  *  waiting.
        !            31:  *
        !            32:  * Parameters:
        !            33:  *  lpBZ            LPOLEUIBUSY pointing to the in-out structure
        !            34:  *                  for this dialog.
        !            35:  *
        !            36:  * Return Value:
        !            37:  *              OLEUI_BZERR_HTASKINVALID  : Error
        !            38:  *              OLEUI_BZ_SWITCHTOSELECTED : Success, user selected "switch to"
        !            39:  *              OLEUI_BZ_RETRYSELECTED    : Success, user selected "retry"
        !            40:  *              OLEUI_CANCEL              : Success, user selected "cancel"
        !            41:  */
        !            42:  
        !            43: STDAPI_(UINT) OleUIBusy(LPOLEUIBUSY lpOBZ)
        !            44:     {
        !            45:     UINT        uRet = 0;
        !            46:     HGLOBAL     hMemDlg=NULL;
        !            47: 
        !            48: #if defined( NT_BUG )
        !            49: 
        !            50:     uRet=UStandardValidation((LPOLEUISTANDARD)lpOBZ, sizeof(OLEUIBUSY)
        !            51:                              , &hMemDlg);
        !            52:                              
        !            53:     // Error out if the standard validation failed
        !            54:     if (OLEUI_SUCCESS!=uRet)
        !            55:         return uRet;
        !            56: 
        !            57: #if !defined( WIN32 )
        !            58:     // Validate HTASK
        !            59:     if (!IsTask(lpOBZ->hTask))
        !            60:         uRet = OLEUI_BZERR_HTASKINVALID;
        !            61: #endif
        !            62:         
        !            63:     // Error out if our secondary validation failed        
        !            64:     if (OLEUI_ERR_STANDARDMIN <= uRet)
        !            65:         {
        !            66:         if (NULL!=hMemDlg)
        !            67:             FreeResource(hMemDlg);
        !            68: 
        !            69:         return uRet;
        !            70:         }
        !            71: 
        !            72:     // Invoke the dialog.
        !            73:     uRet=UStandardInvocation(BusyDialogProc, (LPOLEUISTANDARD)lpOBZ,
        !            74:                              hMemDlg, MAKEINTRESOURCE(IDD_BUSY));
        !            75: #endif
        !            76: 
        !            77:     return uRet;
        !            78: }
        !            79: 
        !            80: 
        !            81: /*
        !            82:  * BusyDialogProc
        !            83:  *
        !            84:  * Purpose:
        !            85:  *  Implements the OLE Busy dialog as invoked through the OleUIBusy function.
        !            86:  *
        !            87:  * Parameters:
        !            88:  *  Standard
        !            89:  *
        !            90:  * Return Value:
        !            91:  *  Standard
        !            92:  *
        !            93:  */
        !            94: 
        !            95: BOOL CALLBACK EXPORT BusyDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
        !            96:     {
        !            97:     LPBUSY         lpBZ;
        !            98:     UINT           uRet = 0;   
        !            99: 
        !           100:     //Declare Win16/Win32 compatible WM_COMMAND parameters.
        !           101:     COMMANDPARAMS(wID, wCode, hWndMsg);
        !           102: 
        !           103:     //This will fail under WM_INITDIALOG, where we allocate it.
        !           104:     lpBZ=(LPBUSY)LpvStandardEntry(hDlg, iMsg, wParam, lParam, &uRet);
        !           105: 
        !           106:     //If the hook processed the message, we're done.
        !           107:     if (0!=uRet)
        !           108:         return (BOOL)uRet;
        !           109: 
        !           110:     //Process the temination message
        !           111:     if (iMsg==uMsgEndDialog)
        !           112:     {
        !           113:         BusyCleanup(hDlg);
        !           114:         StandardCleanup(lpBZ, hDlg);
        !           115:         EndDialog(hDlg, wParam);
        !           116:         return TRUE;
        !           117:     }
        !           118:     
        !           119:     // Process our special "close" message.  If we get this message,
        !           120:     // this means that the call got unblocked, so we need to
        !           121:     // return OLEUI_BZ_CALLUNBLOCKED to our calling app.
        !           122:     if (iMsg == uMsgCloseBusyDlg)
        !           123:     {
        !           124:         SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_CALLUNBLOCKED, 0L);
        !           125:         return TRUE;
        !           126:     }
        !           127:         
        !           128:     switch (iMsg)
        !           129:         {
        !           130:         case WM_INITDIALOG:
        !           131:             FBusyInit(hDlg, wParam, lParam);
        !           132:             return TRUE;
        !           133: 
        !           134:         case WM_COMMAND:
        !           135:             switch (wID)
        !           136:                 {
        !           137:                 case IDBZ_SWITCHTO:
        !           138:                 
        !           139:                     // If user selects "Switch To...", switch activation 
        !           140:                     // directly to the window which is causing the problem.  
        !           141:                     if (IsWindow(lpBZ->hWndBlocked))
        !           142:                         MakeWindowActive(lpBZ->hWndBlocked);
        !           143:                     else                        
        !           144:                         StartTaskManager(); // Fail safe: Start Task Manager
        !           145: 
        !           146:                     // If this is the app not responding case, then we want
        !           147:                     // to bring down the dialog when "SwitchTo" is selected.
        !           148:                     // If the app is busy (RetryRejectedCall situation) then
        !           149:                     // we do NOT want to bring down the dialog. this is 
        !           150:                     // the OLE2.0 user model design.
        !           151:                     if (lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG)
        !           152:                         SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_SWITCHTOSELECTED, 0L);
        !           153:                     break;
        !           154: 
        !           155:                 case IDBZ_RETRY:
        !           156:                     SendMessage(hDlg, uMsgEndDialog, OLEUI_BZ_RETRYSELECTED, 0L);
        !           157:                     break;
        !           158: 
        !           159:                 case IDCANCEL:
        !           160:                     SendMessage(hDlg, uMsgEndDialog, OLEUI_CANCEL, 0L);
        !           161:                     break;
        !           162:                 }
        !           163:             break;
        !           164:         }
        !           165:     return FALSE;
        !           166:     }
        !           167: 
        !           168: 
        !           169: /*
        !           170:  * FBusyInit
        !           171:  *
        !           172:  * Purpose:
        !           173:  *  WM_INITIDIALOG handler for the Busy dialog box.
        !           174:  *
        !           175:  * Parameters:
        !           176:  *  hDlg            HWND of the dialog
        !           177:  *  wParam          WPARAM of the message
        !           178:  *  lParam          LPARAM of the message
        !           179:  *
        !           180:  * Return Value:
        !           181:  *  BOOL            Value to return for WM_INITDIALOG.
        !           182:  */
        !           183: 
        !           184: BOOL FBusyInit(HWND hDlg, WPARAM wParam, LPARAM lParam)
        !           185:     {
        !           186:     LPBUSY           lpBZ;
        !           187:     LPOLEUIBUSY      lpOBZ;
        !           188:     HFONT            hFont;
        !           189:     LPSTR            lpTaskName;
        !           190:     LPSTR            lpWindowName;
        !           191:     HICON            hIcon;  
        !           192: 
        !           193:     lpBZ=(LPBUSY)LpvStandardInit(hDlg, sizeof(OLEUIBUSY), TRUE, &hFont);
        !           194: 
        !           195:     // PvStandardInit sent a termination to us already.
        !           196:     if (NULL==lpBZ)
        !           197:         return FALSE;
        !           198:     
        !           199:     // Our original structure is in lParam    
        !           200:     lpOBZ = (LPOLEUIBUSY)lParam;          
        !           201:     
        !           202:     // Copy it to our instance of the structure (in lpBZ)
        !           203:     lpBZ->lpOBZ=lpOBZ;
        !           204: 
        !           205:     //Copy other information from lpOBZ that we might modify.
        !           206:     lpBZ->dwFlags = lpOBZ->dwFlags;
        !           207: 
        !           208:     // Set default information    
        !           209:     lpBZ->hWndBlocked = NULL;
        !           210:     
        !           211:     // Insert HWND of our dialog into the address pointed to by
        !           212:     // lphWndDialog.  This can be used by the app who called
        !           213:     // OleUIBusy to bring down the dialog with uMsgCloseBusyDialog
        !           214:     if (lpOBZ->lphWndDialog && 
        !           215:         !IsBadWritePtr((VOID FAR *)lpOBZ->lphWndDialog, sizeof(HWND)))
        !           216:         {
        !           217:         *lpOBZ->lphWndDialog = hDlg;
        !           218:         }
        !           219:     
        !           220:     // Update text in text box -- 
        !           221:     // GetTaskInfo will return two pointers, one to the task name
        !           222:     // (file name) and one to the window name.  We need to call
        !           223:     // IMallocMemFree on these when we're done with them.  We also
        !           224:     // get the HWND which is blocked in this call
        !           225:     //
        !           226:     // In the case where this call fails, a default message should already
        !           227:     // be present in the dialog template, so no action is needed
        !           228:     
        !           229:     if (GetTaskInfo(hDlg, lpOBZ->hTask, &lpTaskName, &lpWindowName, &lpBZ->hWndBlocked))
        !           230:         {                   
        !           231:         // Build string to present to user, place in IDBZ_MESSAGE1 control
        !           232:         BuildBusyDialogString(hDlg, lpBZ->dwFlags, IDBZ_MESSAGE1, lpTaskName, lpWindowName);
        !           233:         IMallocMemFree(lpTaskName);
        !           234:         IMallocMemFree(lpWindowName);
        !           235:         }
        !           236:       
        !           237:     // Update icon with the system "exclamation" icon
        !           238:     hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
        !           239:     SendDlgItemMessage(hDlg, IDBZ_ICON, STM_SETICON, (WPARAM)hIcon, 0L);
        !           240:     
        !           241:     // Disable/Enable controls
        !           242:     if ((lpBZ->dwFlags & BZ_DISABLECANCELBUTTON) ||
        !           243:         (lpBZ->dwFlags & BZ_NOTRESPONDINGDIALOG))              // Disable cancel for "not responding" dialog
        !           244:         EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);  
        !           245: 
        !           246:     if (lpBZ->dwFlags & BZ_DISABLESWITCHTOBUTTON)
        !           247:         EnableWindow(GetDlgItem(hDlg, IDBZ_SWITCHTO), FALSE);
        !           248:         
        !           249:     if (lpBZ->dwFlags & BZ_DISABLERETRYBUTTON)
        !           250:         EnableWindow(GetDlgItem(hDlg, IDBZ_RETRY), FALSE);
        !           251: 
        !           252:     // Call the hook with lCustData in lParam
        !           253:     UStandardHook((LPVOID)lpBZ, hDlg, WM_INITDIALOG, wParam, lpOBZ->lCustData);
        !           254: 
        !           255:     // Update caption if lpszCaption was specified
        !           256:     if (lpBZ->lpOBZ->lpszCaption && !IsBadReadPtr(lpBZ->lpOBZ->lpszCaption, 1)
        !           257:           && lpBZ->lpOBZ->lpszCaption[0] != '\0')
        !           258:         SetWindowText(hDlg, (LPSTR)lpBZ->lpOBZ->lpszCaption);
        !           259: 
        !           260:     return TRUE;
        !           261:     }
        !           262: 
        !           263: 
        !           264: /*
        !           265:  * BuildBusyDialogString
        !           266:  *
        !           267:  * Purpose:
        !           268:  *  Builds the string that will be displayed in the dialog from the
        !           269:  *  task name and window name parameters.
        !           270:  *
        !           271:  * Parameters:
        !           272:  *  hDlg            HWND of the dialog     
        !           273:  *  dwFlags         DWORD containing flags passed into dialog
        !           274:  *  iControl        Control ID to place the text string
        !           275:  *  lpTaskName      LPSTR pointing to name of task (e.g. C:\TEST\TEST.EXE)
        !           276:  *  lpWindowName    LPSTR for name of window
        !           277:  *
        !           278:  * Caveats:
        !           279:  *  The caller of this function MUST de-allocate the lpTaskName and
        !           280:  *  lpWindowName pointers itself with IMallocMemFree.
        !           281:  *
        !           282:  * Return Value:
        !           283:  *  void
        !           284:  */
        !           285: 
        !           286: void BuildBusyDialogString(HWND hDlg, DWORD dwFlags, int iControl, LPSTR lpTaskName, LPSTR lpWindowName)
        !           287: {
        !           288:     LPSTR       pszT, psz1, psz2, psz3;
        !           289:     UINT        cch;
        !           290:     LPSTR       pszDot, pszSlash;
        !           291:     UINT        uiStringNum;
        !           292:     
        !           293:     /*
        !           294:      * We need scratch memory for loading the stringtable string, 
        !           295:      * the task name, and constructing the final string.  We therefore 
        !           296:      * allocate three buffers as large as the maximum message 
        !           297:      * length (512) plus the object type, guaranteeing that we have enough
        !           298:      * in all cases.
        !           299:      */
        !           300:     cch=512;
        !           301:     
        !           302:     // Use OLE-supplied allocation
        !           303:     if ((pszT = IMallocMemAlloc((DWORD)(3*cch))) == NULL)
        !           304:         return;
        !           305:              
        !           306:     psz1=pszT;
        !           307:     psz2=psz1+cch;
        !           308:     psz3=psz2+cch;
        !           309:     
        !           310:     // Parse base name out of path name, use psz2 for the task
        !           311:     // name to display
        !           312:     
        !           313:     _fstrcpy(psz2, lpTaskName);
        !           314:     pszDot = _fstrrchr(psz2, '.');
        !           315:     if (pszDot != NULL)
        !           316:       *pszDot = '\0'; // Null terminate at the DOT
        !           317: 
        !           318:     pszSlash = _fstrrchr(psz2, '\\'); // Find last backslash in path
        !           319:     if (pszSlash != NULL)
        !           320:       psz2 = pszSlash + 1; // Nuke everything up to this point
        !           321:     
        !           322: #ifdef LOWERCASE_NAME      
        !           323:     // Compile this with /DLOWERCASE_NAME if you want the lower-case
        !           324:     // module name to be displayed in the dialog rather than the
        !           325:     // all-caps name.
        !           326:     {
        !           327:     int i,l;
        !           328:     
        !           329:     // Now, lowercase all letters except first one
        !           330:     l = _fstrlen(psz2);
        !           331:     for(i=0;i<l;i++)
        !           332:       psz2[i] = tolower(psz2[i]);
        !           333:       
        !           334:     psz2[0] = toupper(psz2[0]);  
        !           335:     }
        !           336: #endif
        !           337:     
        !           338:     // Check size of lpWindowName.  We can reasonably fit about 80 
        !           339:     // characters into the text control, so truncate more than 80 chars
        !           340:     if (_fstrlen(lpWindowName) > 80)
        !           341:       lpWindowName[80] = '\0';
        !           342:       
        !           343:     // Load the format string out of stringtable, choose a different
        !           344:     // string depending on what flags are passed in to the dialog
        !           345:     if (dwFlags & BZ_NOTRESPONDINGDIALOG)
        !           346:         uiStringNum = IDS_BZRESULTTEXTNOTRESPONDING;
        !           347:     else
        !           348:         uiStringNum = IDS_BZRESULTTEXTBUSY;
        !           349: 
        !           350:     if (LoadString(ghInst, uiStringNum, psz1, cch) == 0)
        !           351:       return;
        !           352: 
        !           353:     // Build the string. The format string looks like this:
        !           354:     // "This action cannot be completed because the '%s' application 
        !           355:     // (%s) is [busy | not responding]. Choose \"Switch To\" to activate '%s' and 
        !           356:     // correct the problem."
        !           357:     
        !           358:     wsprintf(psz3, psz1, (LPSTR)psz2, (LPSTR)lpWindowName, (LPSTR)psz2);
        !           359:     SetDlgItemText(hDlg, iControl, (LPSTR)psz3);
        !           360:     IMallocMemFree(pszT);
        !           361:     
        !           362:     return;
        !           363: }
        !           364: 
        !           365: 
        !           366: 
        !           367: /*
        !           368:  * BusyCleanup
        !           369:  *
        !           370:  * Purpose:
        !           371:  *  Performs busy-specific cleanup before termination.
        !           372:  *
        !           373:  * Parameters:
        !           374:  *  hDlg            HWND of the dialog box so we can access controls.
        !           375:  *
        !           376:  * Return Value:
        !           377:  *  None
        !           378:  */
        !           379: void BusyCleanup(HWND hDlg)
        !           380: {
        !           381:    return;
        !           382: }
        !           383: 
        !           384: 
        !           385: 
        !           386: /*
        !           387:  * GetTaskInfo()
        !           388:  *
        !           389:  * Purpose:  Gets information about the specified task and places the
        !           390:  * module name, window name and top-level HWND for the task in the specified 
        !           391:  * pointers
        !           392:  *
        !           393:  * NOTE: The two string pointers allocated in this routine are
        !           394:  * the responsibility of the CALLER to de-allocate.
        !           395:  *
        !           396:  * Parameters:
        !           397:  *    hWnd             HWND who called this function
        !           398:  *    htask            HTASK which we want to find out more info about
        !           399:  *    lplpszTaskName   Location that the module name is returned
        !           400:  *    lplpszWindowName Location where the window name is returned
        !           401:  *
        !           402:  */
        !           403:     
        !           404: BOOL GetTaskInfo(HWND hWnd, HTASK htask, LPSTR FAR* lplpszTaskName, LPSTR FAR*lplpszWindowName, HWND FAR*lphWnd)
        !           405: {
        !           406:     BOOL        fRet = FALSE;
        !           407: #if !defined( WIN32 )
        !           408:     TASKENTRY   te;
        !           409: #endif
        !           410:     HWND        hwndNext;
        !           411:     LPSTR       lpszTN = NULL;
        !           412:     LPSTR       lpszWN = NULL;
        !           413:     HWND        hwndFind = NULL;
        !           414:                    
        !           415:     // Clear out return values in case of error                   
        !           416:     *lplpszTaskName = NULL;
        !           417:     *lplpszWindowName = NULL;
        !           418:                    
        !           419: #if !defined( WIN32 )
        !           420:     te.dwSize = sizeof(TASKENTRY);                   
        !           421:     if (TaskFindHandle(&te, htask))
        !           422: #endif
        !           423:         {
        !           424:         // Now, enumerate top-level windows in system
        !           425:         hwndNext = GetWindow(hWnd, GW_HWNDFIRST);
        !           426:         while (hwndNext)
        !           427:             {
        !           428:             // See if we can find a non-owned top level window whose
        !           429:             // hInstance matches the one we just got passed.  If we find one,
        !           430:             // we can be fairly certain that this is the top-level window for
        !           431:             // the task which is blocked.
        !           432:             //
        !           433:             // REVIEW:  Will this filter hold true for InProcServer DLL-created
        !           434:             // windows?
        !           435:             //
        !           436:             if ((hwndNext != hWnd) &&
        !           437: #if !defined( WIN32 )
        !           438:                 (GetWindowWord(hwndNext, GWW_HINSTANCE) == (WORD)te.hInst) &&
        !           439: #else                     
        !           440:                 (GetWindowThreadProcessId(hwndNext,NULL) == htask) &&
        !           441: #endif                     
        !           442:                                (IsWindowVisible(hwndNext)) &&
        !           443:                 !GetWindow(hwndNext, GW_OWNER))
        !           444:                 {
        !           445:                 // We found our window!  Alloc space for new strings
        !           446:                 if ((lpszTN = IMallocMemAlloc(OLEUI_CCHPATHMAX)) == NULL)
        !           447:                     return TRUE;  // continue task window enumeration
        !           448:                    
        !           449:                 if ((lpszWN = IMallocMemAlloc(OLEUI_CCHPATHMAX)) == NULL)
        !           450:                     return TRUE;  // continue task window enumeration
        !           451:                     
        !           452:                 // We found the window we were looking for, copy info to
        !           453:                 // local vars
        !           454:                 GetWindowText(hwndNext, lpszWN, OLEUI_CCHPATHMAX);
        !           455: #if !defined( WIN32 )
        !           456:                  lstrcpyn(lpszTN, te.szModule, OLEUI_CCHPATHMAX);
        !           457: #else                     
        !           458:                 /* WIN32 NOTE: we are not able to get a module name
        !           459:                 **    given a thread process id on WIN32. the best we
        !           460:                 **    can do is use the window title as the module/app
        !           461:                 **    name.
        !           462:                 */
        !           463:                  lstrcpyn(lpszTN, lpszWN, OLEUI_CCHPATHMAX);
        !           464: #endif                     
        !           465:                 hwndFind = hwndNext;
        !           466:                 
        !           467:                 fRet = TRUE;
        !           468:                 goto OKDone;
        !           469:                 }
        !           470:                 
        !           471:             hwndNext = GetWindow(hwndNext, GW_HWNDNEXT);
        !           472:             }
        !           473:         }
        !           474: 
        !           475: OKDone:
        !           476: 
        !           477:     // OK, everything was successful. Set string pointers to point to
        !           478:     // our data.
        !           479:     
        !           480:     *lplpszTaskName = lpszTN;
        !           481:     *lplpszWindowName = lpszWN;
        !           482:     *lphWnd = hwndFind;
        !           483:     
        !           484:     return fRet;
        !           485: }
        !           486: 
        !           487: 
        !           488: /*
        !           489:  * IMallocMemAlloc()
        !           490:  *
        !           491:  * Purpose: Allocates dwSize bytes of memory using the OLE-supplied
        !           492:  * memory allocation.
        !           493:  *
        !           494:  * Parameters:
        !           495:  *    dwSize           Size of memory requested
        !           496:  *
        !           497:  * Returns:
        !           498:  *    void FAR *       Pointer to new memory, or NULL if failed
        !           499:  *
        !           500:  */
        !           501:  
        !           502: void FAR * IMallocMemAlloc(DWORD dwSize)
        !           503: {
        !           504:   LPMALLOC pIMalloc;
        !           505:   LPSTR pszT;
        !           506:   
        !           507:   // Use OLE-supplied allocation
        !           508:   if (CoGetMalloc(MEMCTX_TASK, &pIMalloc) != NOERROR)
        !           509:      return NULL;
        !           510: 
        !           511:   pszT=(LPSTR)pIMalloc->lpVtbl->Alloc(pIMalloc, dwSize);
        !           512:   pIMalloc->lpVtbl->Release(pIMalloc);
        !           513:   return pszT;
        !           514: }    
        !           515: 
        !           516: 
        !           517: /*
        !           518:  * IMallocMemFree()
        !           519:  *
        !           520:  * Purpose: Frees memory allocated with IMallocMemAlloc()
        !           521:  *
        !           522:  * Parameters:
        !           523:  *    ptr              Pointer to memory to free
        !           524:  *
        !           525:  * Returns:
        !           526:  *    SCODE            Return code from CoGetMalloc
        !           527:  */
        !           528:     
        !           529: SCODE IMallocMemFree(void FAR *ptr)
        !           530: {
        !           531:   SCODE sc;
        !           532:   LPMALLOC pIMalloc;
        !           533:   
        !           534:   sc = GetScode(CoGetMalloc(MEMCTX_TASK, &pIMalloc));
        !           535:   if (SUCCEEDED(sc))
        !           536:     {
        !           537:     pIMalloc->lpVtbl->Free(pIMalloc, ptr);
        !           538:     pIMalloc->lpVtbl->Release(pIMalloc);
        !           539:     }
        !           540:   return sc;
        !           541:   
        !           542: }
        !           543: 
        !           544: 
        !           545: /*
        !           546:  * StartTaskManager()
        !           547:  *
        !           548:  * Purpose: Starts Task Manager.  Used to bring up task manager to
        !           549:  * assist in switching to a given blocked task.
        !           550:  *
        !           551:  */
        !           552:  
        !           553: StartTaskManager()
        !           554: {
        !           555:     WinExec("taskman.exe", SW_SHOW);
        !           556:     return TRUE;
        !           557: }    
        !           558: 
        !           559: 
        !           560: 
        !           561: /*
        !           562:  * MakeWindowActive()
        !           563:  *
        !           564:  * Purpose: Makes specified window the active window.
        !           565:  *
        !           566:  */
        !           567: 
        !           568: void MakeWindowActive(HWND hWndSwitchTo)
        !           569: {
        !           570:     // Move the new window to the top of the Z-order
        !           571:     SetWindowPos(hWndSwitchTo, HWND_TOP, 0, 0, 0, 0,
        !           572:               SWP_NOSIZE | SWP_NOMOVE);
        !           573: 
        !           574:     // If it's iconic, we need to restore it.
        !           575:     if (IsIconic(hWndSwitchTo))
        !           576:         ShowWindow(hWndSwitchTo, SW_RESTORE);
        !           577: }

unix.superglobalmegacorp.com

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