YIELDC.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:26k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /****************************************************************************
  2.                    Microsoft RPC Version 2.0
  3.            Copyright Microsoft Corp. 1992, 1993, 1994- 1996
  4.                        yield Example
  5.     FILE:       yieldp.c
  6.     PURPOSE:    RPC sample Windows client
  7.                 Based on Win 3.x SDK Generic template for Windows applications
  8.     FUNCTIONS:  WinMain()         - same as Windows generic example
  9.                 InitApplication() - same as Windows generic example
  10.                 InitInstance()    - same as Windows generic example
  11.                 MainWndProc()     - processes messages
  12.                 About()     - processes messages for "About" dialog box
  13.                 BindInfo()  - processes messages for "Bind" dialog box
  14.                 WaitInfo()  - processes messages for "Wait" dialog box
  15.                 YieldInfo() - processes messages for "Yield" dialog box
  16.                 Bind()               - calls the RPC API functions
  17.                 midl_user_allocate() - memory allocation function needed by RPC
  18.                 midl_user_free()     - memory free function needed by RPC
  19.     COMMENTS:   This sample application demonstrates the yield capability
  20.                 of the Microsoft RPC for Microsoft Windows 3.x using the
  21.                 RpcWinSetYieldInfo API function.
  22.                 By yielding, you can prevent your distributed application
  23.                 from blocking during lengthy remote procedure calls.
  24.                 This sample is based on the Win 3.x generic example. To focus
  25.                 attention on the RPC-related aspects of this application,
  26.                 many comments from the Windows-only version are removed.
  27. ****************************************************************************/
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <windows.h>
  32. #include <windowsx.h>
  33. #include "yield.h"     // header file generated by MIDL compiler
  34. #include "yieldc.h"    // client-specific header file
  35. /* global data */
  36. unsigned char   pszProtocolSequence[MAXPROTSEQ+1];
  37. unsigned char   pszNetworkAddress[NETLEN+1];
  38. unsigned char   pszEndpoint[PATHLEN+1];
  39. unsigned char * pszUuid           = NULL;
  40. unsigned char * pszOptions        = NULL;
  41. unsigned char * pszStringBinding  = NULL;
  42. int fBound = FALSE;    // flag indicates whether client is bound to server
  43. int fCancel = FALSE;   // flag indicates whether the user has chosen CANCEL
  44. unsigned int cWaitSec; // parameter to remote procedure Sleep()
  45. int   fCustomYield;    // TRUE = custom yield, FALSE = standard yield
  46. DWORD dwOtherInfo;     // depends on the value of fCustomYield
  47. HANDLE  hInst;         // current instance
  48. HCURSOR hHourGlass;    // during calls to RPC API functions
  49. HWND    hWndMain;      // main handle
  50. /****************************************************************************
  51.     FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
  52.     PURPOSE:  Calls initialization function, processes message loop
  53.     COMMENTS: Windows recognizes this function by name as the initial
  54.               entry point for the program.  This function calls the
  55.               application initialization routine, if no other instance
  56.               of the program is running, and always calls the instance
  57.               initialization routine.  It then executes a message
  58.               retrieval and dispatch loop that is the top-level control
  59.               structure for the remainder of execution.  The loop is
  60.               terminated when a WM_QUIT message is received, at which
  61.               time this function exits the application instance by
  62.               returning the value passed by PostQuitMessage().
  63.               If this function must abort before entering the message
  64.               loop, it returns the conventional value NULL.
  65. ****************************************************************************/
  66. int WINAPI WinMain(HINSTANCE hInstance,      // current instance
  67.                    HINSTANCE hPrevInstance,  // previous instance
  68.                    LPSTR     lpCmdLine,      // command line
  69.                    int       nCmdShow)       // show-window type
  70. {
  71.     MSG msg;
  72.     UNREFERENCED_PARAMETER(lpCmdLine);
  73.     if (! hPrevInstance)                   // no other instances of app running
  74.         if (! InitApplication(hInstance))  // initialize shared things
  75.             return(FALSE);                 // exit if unable to initialize
  76.     /* Perform initializations that apply to a specific instance */
  77.     if (! InitInstance(hInstance, nCmdShow))
  78.         return(FALSE);
  79.     /* Acquire and dispatch messages until a WM_QUIT message is received */
  80.     while (GetMessage(&msg,        // message structure
  81.                       (HWND)NULL,  // handle of window receiving the message
  82.                       0,           // lowest message to examine
  83.                       0))          // highest message to examine
  84.     {
  85.         TranslateMessage(&msg);    // translate virtual key codes
  86.         DispatchMessage(&msg);     // dispatche message to window
  87.     }
  88.     return(msg.wParam);  // return the value from PostQuitMessage
  89. }
  90. /****************************************************************************
  91.     FUNCTION: InitApplication(HANDLE)
  92.     PURPOSE:  Initializes window data and registers window class
  93.     COMMENTS: This function is called at initialization time only if
  94.               no other instances of the application are running.  This
  95.               function performs initialization tasks that can be done
  96.               once for any number of running instances.
  97.               In this case, we initialize a window class by filling out
  98.               a data structure of type WNDCLASS and calling the Windows
  99.               RegisterClass() function.  Since all instances of this
  100.               application use the same window class, we only need to do
  101.               this when the first instance is initialized.
  102. ****************************************************************************/
  103. BOOL InitApplication(HANDLE hInstance)    // current instance
  104. {
  105.     WNDCLASS wc;
  106.     /* Fill in the window class structure with parameters that   */
  107.     /* describe the main window                                  */
  108.     wc.style         = 0;
  109.     wc.lpfnWndProc   = (WNDPROC) MainWndProc;
  110.     wc.cbClsExtra    = 0;
  111.     wc.cbWndExtra    = 0;
  112.     wc.hInstance     = hInstance;
  113.     wc.hIcon         = LoadIcon(hInstance, "YieldIcon");
  114.     wc.hCursor       = LoadCursor((HANDLE) NULL, IDC_ARROW);
  115.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  116.     wc.lpszMenuName  = "GenericMenu";
  117.     wc.lpszClassName = "GenericWClass";
  118.     /* Register the window class and return success/failure code */
  119.     return(RegisterClass(&wc));
  120. }
  121. /****************************************************************************
  122.     FUNCTION:  InitInstance(HANDLE, int)
  123.     PURPOSE:   Saves instance handle and creates main window
  124.     COMMENTS:  This function is called at initialization time for every
  125.                instance of this application.  This function performs
  126.                initialization tasks that cannot be shared by multiple
  127.                instances.
  128.                In this case, we save the instance handle in a global
  129.                variable and create and display the main program window.
  130. ****************************************************************************/
  131. BOOL InitInstance(HANDLE  hInstance,    // current instance
  132.                   int     nCmdShow)     // param for first ShowWindow() call
  133. {
  134.     HWND hWnd;
  135.     /* Save the instance handle in global variable, which will be used */
  136.     /* in many subsequence calls from this application to Windows      */
  137.     hInst = hInstance;
  138.     hHourGlass = LoadCursor((HANDLE) NULL, IDC_WAIT);
  139.     /* Create a main window for this application instance */
  140.     hWnd = CreateWindow("GenericWClass",
  141.                         "RPC Sample Application",
  142.                         WS_OVERLAPPEDWINDOW,
  143.                         CW_USEDEFAULT,
  144.                         CW_USEDEFAULT,
  145.                         CW_USEDEFAULT,
  146.                         CW_USEDEFAULT,
  147.                         (HWND) NULL,
  148.                         (HMENU) NULL,
  149.                         hInstance,
  150.                         (LPVOID) NULL
  151.                         );
  152.     /* If the window cannot be created, return "failure" */
  153.     if (!hWnd)
  154.         return(FALSE);
  155.     /* Initialize RPC binding data */
  156.     strcpy(pszProtocolSequence, DEFAULT_PROT_SEQ);
  157.     strcpy(pszEndpoint, DEFAULT_ENDPOINT);
  158.     pszNetworkAddress[0] = '';
  159.     /* Bind client to server */
  160.     fBound = FALSE;
  161.     /* Initialize the parameter to the remote procedure Sleep() */
  162.     cWaitSec = DEFAULT_WAIT;
  163.     /* Initialize the parameters to RpcWinSetYieldInfo() */
  164.     fCustomYield = FALSE;         // FALSE = std yield
  165.     dwOtherInfo = (DWORD) NULL;   // NULL = RPC-supplied dialog box
  166.     RpcWinSetYieldInfo(hWnd,                  // handle
  167.                        fCustomYield,          // standard or custom yield?
  168.                        WM_RPC_YIELD_MESSAGE,  // 0 = no message is posted
  169.                        dwOtherInfo);          // depends on fCustomYield value
  170.     /* Make the window visible, update its client area, and return "success" */
  171.     ShowWindow(hWnd, nCmdShow);
  172.     UpdateWindow(hWnd);
  173.     return(TRUE);
  174. }
  175. /****************************************************************************
  176.     FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
  177.     PURPOSE:  Processes messages
  178.     MESSAGES: WM_COMMAND  - application menu (About dialog box)
  179.               WM_DESTROY  - destroy window
  180.     COMMENTS: Based on the Windows generic sample.
  181.               Several new menu items are added to demonstrate the
  182.               RpcWinSetYieldInfo function.
  183.               The "Bind" menu is associated with the "GetBindInfo"
  184.               dialog box function.  GetBindInfo allows the user to
  185.               set the parameters for the RpcStringBindingCompose and
  186.               RpcBindingFromStringBinding functions.  A flag, fBound,
  187.               keeps track of whether the client application is bound
  188.               to a remote server.  If this flag indicates that the
  189.               client application is not bound to the server, it calls
  190.               the "Bind" utility function to call the
  191.               RPC API functions that establish the binding.
  192.               The "Yield" menu is associated with the "GetYieldInfo"
  193.               dialog box function. GetYieldInfo allows the user to
  194.               select the yielding model:  standard yield with an
  195.               RPC run-time library-supplied dialog box; standard
  196.               yield with a user-supplied dialog box; or custom yield.
  197.               These methods are described in detail in the documentation
  198.               for the RpcWinSetYieldInfo function.
  199. ****************************************************************************/
  200. long APIENTRY MainWndProc(HWND hWnd,       // window handle
  201.                           UINT message,    // type of message
  202.                           WPARAM wParam,   // additional information
  203.                           LPARAM lParam    // additional information
  204.                           )
  205. {
  206.     DLGPROC lpProc;    // pointer to the dialog box function
  207.     /* copy the window handle for CustomYield() */
  208.     hWndMain = hWnd;
  209.     switch (message) {
  210.     case WM_CREATE:
  211.         /* Win 3.x is client-only; force user to specify server */
  212.         PostMessage(hWnd, WM_COMMAND, IDM_BIND, 0L);
  213.         break;
  214.     case WM_COMMAND:
  215.         switch (wParam) {
  216.         case IDM_ABOUT:
  217.             lpProc = MakeProcInstance(About, hInst);
  218.             DialogBox(hInst,
  219.                       "AboutBox",
  220.                       hWnd,
  221.                       lpProc);
  222.             FreeProcInstance(lpProc);
  223.             break;
  224.         case IDM_BIND:
  225.             lpProc = MakeProcInstance(GetBindInfo, hInst);
  226.             DialogBox(hInst,
  227.                       "BindBox",
  228.                       hWnd,
  229.                       lpProc);
  230.             FreeProcInstance(lpProc);
  231.             break;
  232.         case IDM_WAIT:
  233.             lpProc = MakeProcInstance(GetWaitInfo, hInst);
  234.             DialogBox(hInst,
  235.                       "WaitBox",
  236.                       hWnd,
  237.                       lpProc);
  238.             FreeProcInstance(lpProc);
  239.             break;
  240.         case IDM_YIELD:
  241.             lpProc = MakeProcInstance(GetYieldInfo, hInst);
  242.             DialogBox(hInst,
  243.                       "YieldBox",
  244.                       hWnd,
  245.                       lpProc);
  246.             FreeProcInstance(lpProc);
  247.             break;
  248.         case IDM_EXIT:
  249.             DestroyWindow(hWnd);
  250.             if (fBound == TRUE) {
  251.                 RpcTryExcept {
  252.                     Shutdown();     // shut down the server
  253.                 }
  254.                 RpcExcept(1) {
  255.                     MessageBox(hWnd,
  256.                                EXCEPT_MSG,
  257.                                "Remote Procedure Call",
  258.                                MB_ICONINFORMATION);
  259.                 }
  260.                 RpcEndExcept
  261.             }
  262.             break;
  263.         default:
  264.             return(DefWindowProc(hWnd, message, wParam, lParam));
  265.         }
  266.         break;
  267.     case WM_RPC_YIELD_MESSAGE:   // signals beginning or end of yield period
  268.         if (wParam == 0)
  269.             SetWindowText(hWnd, YIELD_END_MSG);
  270.         else if (wParam == 1)
  271.             SetWindowText(hWnd, YIELD_START_MSG);
  272.         break;
  273.     case WM_DESTROY:
  274.         PostQuitMessage(0);
  275.         break;
  276.     default:  // passes it on if unprocessed
  277.         return(DefWindowProc(hWnd, message, wParam, lParam));
  278.     }
  279.     return(0L);
  280. }
  281. /****************************************************************************
  282.     FUNCTION: About(HWND, unsigned, WORD, LONG)
  283.     PURPOSE:  "About" dialog box
  284.     COMMENTS:
  285. ****************************************************************************/
  286. BOOL APIENTRY About(HWND hDlg,
  287.                     UINT message,
  288.                     UINT wParam,
  289.                     LONG lParam)
  290. {
  291.     UNREFERENCED_PARAMETER(lParam);
  292.     switch (message) {
  293.     case WM_INITDIALOG:
  294.         return(TRUE);
  295.     case WM_COMMAND:
  296.         if (wParam == IDOK || wParam == IDCANCEL) {
  297.             EndDialog(hDlg, TRUE);
  298.             return(TRUE);
  299.         }
  300.         break;
  301.     }
  302.     return(FALSE);
  303. }
  304. /****************************************************************************
  305.     FUNCTION: GetBindInfo(HWND, unsigned, WORD, LONG)
  306.     PURPOSE:  Collect components of string binding;
  307.               protocol sequence, network address, endpoint
  308.     COMMENTS:
  309. ****************************************************************************/
  310. BOOL APIENTRY GetBindInfo(HWND hDlg,
  311.                           UINT message,
  312.                           UINT wParam,
  313.                           LONG lParam)
  314. {
  315.     HCURSOR hOld;
  316.     UNREFERENCED_PARAMETER(lParam);
  317.     switch (message) {
  318.     case WM_INITDIALOG:  // fill in dialog's edit boxes
  319.         SetDlgItemText(hDlg, IDD_ENDPOINT, pszEndpoint);
  320.         SetDlgItemText(hDlg, IDD_PROT_SEQ, pszProtocolSequence);
  321.         SetDlgItemText(hDlg, IDD_NET_ADDR, pszNetworkAddress);
  322.         return(TRUE);
  323.     case WM_COMMAND:
  324.         switch(wParam) {
  325.         case IDCANCEL:
  326.             EndDialog(hDlg, FALSE);
  327.             return(TRUE);
  328.         case IDOK:
  329.             GetDlgItemText(hDlg, IDD_PROT_SEQ, pszProtocolSequence, MAXPROTSEQ);
  330.             GetDlgItemText(hDlg, IDD_ENDPOINT, pszEndpoint, PATHLEN);
  331.             GetDlgItemText(hDlg, IDD_NET_ADDR, pszNetworkAddress, NETLEN);
  332.             hOld = SetCursor(hHourGlass);
  333.             if (Bind(hDlg) != RPC_S_OK) {  // bind to server
  334.                 EndDialog(hDlg, FALSE);
  335.                 return(FALSE);
  336.             }
  337.             SetCursor(hOld);
  338.             EndDialog(hDlg, TRUE);
  339.             return(TRUE);
  340.        }
  341.     }
  342.     return(FALSE);
  343. }
  344. /****************************************************************************
  345.     FUNCTION: GetWaitInfo(HWND, unsigned, WORD, LONG)
  346.     PURPOSE:  Prompt user for the parameter to the remote call,
  347.               then make the remote procedure call.
  348.     COMMENTS:
  349. ****************************************************************************/
  350. BOOL APIENTRY GetWaitInfo(HWND hDlg,     // window handle of the dialog box
  351.                           UINT message,  // type of message
  352.                           UINT wParam,   // message-specific information
  353.                           LONG lParam)
  354. {
  355.     int fError;
  356.     UNREFERENCED_PARAMETER(lParam);
  357.     switch (message) {
  358.     case WM_INITDIALOG:
  359.         SetDlgItemInt(hDlg, IDD_WAITTIME, cWaitSec, FALSE);
  360.         return(TRUE);
  361.     case WM_COMMAND:
  362.         switch(wParam) {
  363.         case IDCANCEL:
  364.             EndDialog(hDlg, FALSE);
  365.             fCancel = TRUE;
  366.             return(TRUE);
  367.         case IDOK:
  368.             cWaitSec = GetDlgItemInt(hDlg, IDD_WAITTIME, &fError, FALSE);
  369.             if (cWaitSec <= 0)            // check for valid entry
  370.                 cWaitSec = DEFAULT_WAIT;  // set an appropriate value
  371.             RpcTryExcept {
  372.                 YieldProc(cWaitSec);      // make the remote procedure call
  373.             }
  374.             RpcExcept(1) {
  375.                 unsigned long ulCode;
  376.                 char pszFail[MSGLEN];
  377.                 ulCode = RpcExceptionCode();
  378.                 if (ulCode != RPC_S_CALL_FAILED) {
  379.                     sprintf(pszFail, "%s (0x%x)n", EXCEPT_MSG, ulCode);
  380.                     MessageBox(hDlg,
  381.                                pszFail,
  382.                                "Remote Procedure Call",
  383.                                MB_ICONINFORMATION);
  384.                 }
  385.             }
  386.             RpcEndExcept
  387.             EndDialog(hDlg, TRUE);
  388.             return(TRUE);
  389.         }
  390.     }
  391.     return(FALSE);
  392. }
  393. /****************************************************************************
  394.     FUNCTION: CustomYield(void)
  395.     PURPOSE:  Message handler during custom yield
  396.     MESSAGES: WM_RPC_YIELD_MESSAGE - end of yield message
  397.               WM_COMMAND           - Input received
  398.     COMMENTS: The callback function must retrieve messages from the
  399.               message queue.
  400.               The function must return TRUE when the RPC operation
  401.               has completed. The function must return FALSE when the
  402.               user cancels the RPC operation.
  403. ****************************************************************************/
  404. BOOL FAR PASCAL __export CustomYield(void)
  405. {
  406.     MSG msg;
  407.     fCancel = FALSE;
  408.     while (TRUE) {  // message processing
  409.         GetMessage(&msg, (HWND)NULL, 0, 0);
  410.         if (msg.message == WM_RPC_YIELD_MESSAGE)
  411.             return(TRUE);  // RPC operation is complete
  412.         if (fCancel == TRUE)
  413.             return(FALSE);
  414.         TranslateMessage(&msg);
  415.         DispatchMessage(&msg);
  416.     }
  417.     return(TRUE);
  418. }
  419. /****************************************************************************
  420.     FUNCTION: GetYieldInfo(HWND, unsigned, WORD, LONG)
  421.     PURPOSE:  Check radio buttons to see which yield method
  422.               was selected by the user, then set the parameters
  423.               to RpcWinSetYieldInfo and call RpcWinSetYieldInfo.
  424.     COMMENTS:
  425. ****************************************************************************/
  426. BOOL APIENTRY GetYieldInfo(HWND hDlg,     // window handle of the dialog box
  427.                            UINT message,  // type of message
  428.                            UINT wParam,   // message-specific information
  429.                            LONG lParam)
  430. {
  431.     int fCheck;
  432.     UNREFERENCED_PARAMETER(lParam);
  433.     switch (message) {
  434.     case WM_INITDIALOG:  // message: initialize dialog box
  435.         if (fCustomYield)
  436.             CheckRadioButton(hDlg, IDD_STD_RPC, IDD_CUSTOM, IDD_CUSTOM);
  437.         else if (dwOtherInfo != (DWORD) NULL)
  438.             CheckRadioButton(hDlg, IDD_STD_RPC, IDD_CUSTOM, IDD_STD_USER);
  439.         else
  440.             CheckRadioButton(hDlg, IDD_STD_RPC, IDD_CUSTOM, IDD_STD_RPC);
  441.         return(TRUE);
  442.     case WM_COMMAND:     // message: received a command
  443.         switch(wParam) {
  444.             case IDCANCEL:   // System menu close command?
  445.                 EndDialog(hDlg, FALSE);
  446.                 return(TRUE);
  447.             case IDOK:
  448.                 /* which radio button is checked: Custom yield? */
  449.                 fCheck = (int) SendDlgItemMessage(hDlg,
  450.                                                   IDD_CUSTOM,
  451.                                                   BM_GETCHECK,
  452.                                                   0,
  453.                                                   0);
  454.                 if (fCheck == TRUE) {
  455.                     fCustomYield = TRUE;
  456.                     dwOtherInfo = (DWORD) MakeProcInstance(CustomYield, hInst);
  457.                 }
  458.                 else {
  459.                     fCustomYield = FALSE;
  460.                     /* Standard yield, user-supplied dialog? */
  461.                     fCheck = (int) SendDlgItemMessage(hDlg,
  462.                                                       IDD_STD_USER,
  463.                                                       BM_GETCHECK,
  464.                                                       0,
  465.                                                       0);
  466.                     if (fCheck == TRUE) {
  467.                         HRSRC hrsrc;
  468.                         hrsrc = FindResource(hInst,
  469.                                              "USERYIELDBOX",
  470.                                              RT_DIALOG);
  471.                         dwOtherInfo = LoadResource(hInst, hrsrc);
  472.                     }
  473.                     else {
  474.                         /* Assume standard-yield, rpc-supplied dialog box */
  475.                         dwOtherInfo = (DWORD) NULL;
  476.                     }
  477.                 }
  478.                 RpcWinSetYieldInfo(hWndMain,
  479.                                    fCustomYield,
  480.                                    WM_RPC_YIELD_MESSAGE,
  481.                                    dwOtherInfo);
  482.                 EndDialog(hDlg, TRUE);
  483.                 return(TRUE);
  484.         }
  485.     }
  486.     return(FALSE);
  487. }
  488. /****************************************************************************
  489.     FUNCTION: midl_user_allocate(size_t)
  490.     PURPOSE:  Allocate memory as needed by the RPC runtime library
  491.     COMMENTS: The stubs or runtime libraries may need to allocate memory.
  492.               By convention, they call a user-specified function named
  493.               midl_user_allocate.  In this application, no memory
  494.               management is needed, so a dummy function is provided.
  495. ****************************************************************************/
  496. void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
  497. {
  498.     UNREFERENCED_PARAMETER(len);
  499.     return(NULL);  // no memory management required
  500. }
  501. /****************************************************************************
  502.     FUNCTION: midl_user_free(void *)
  503.     PURPOSE:  Free memory as needed by the RPC runtime library
  504.     COMMENTS: The stubs or runtime libraries may need to free memory.
  505.               By convention, they call a user-specified function named
  506.               midl_user_free.  In this application, no memory allocation
  507.               is needed so a dummy function is provided.
  508. ****************************************************************************/
  509. void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
  510. {
  511.     UNREFERENCED_PARAMETER(ptr);
  512.     return;    // no memory management required
  513. }
  514. /****************************************************************************
  515.     FUNCTION: Bind(HWND)
  516.     PURPOSE:  Make RPC API calls to bind to the server application
  517.     COMMENTS: The binding calls are made from InitInstance() and whenever
  518.               the user changes the protocol sequence, network address, or
  519.               endpoint. If the bind operation is successful, the global
  520.               flag fBound is set to TRUE.
  521.               The global flag fBound is used to determine whether to call
  522.               the RPC API function RpcBindingFree.
  523. ****************************************************************************/
  524. RPC_STATUS Bind(HWND hWnd)
  525. {
  526.     RPC_STATUS status;
  527.     char pszFail[MSGLEN];
  528.     if (fBound == TRUE) {  // unbind only if bound
  529.         status = RpcStringFree(&pszStringBinding);  // remote calls done; unbind
  530.         if (status) {
  531.             MessageBox(hWnd, "RpcStringFree failed", "RPC Error", MB_ICONSTOP);
  532.             return(status);
  533.         }
  534.         status = RpcBindingFree(&hYield);  // remote calls done; unbind
  535.         if (status) {
  536.             MessageBox(hWnd, "RpcBindingFree failed", "RPC Error", MB_ICONSTOP);
  537.             return(status);
  538.         }
  539.         fBound = FALSE;  // unbind successful; reset flag
  540.     }
  541.     status = RpcStringBindingCompose(pszUuid,
  542.                                      pszProtocolSequence,
  543.                                      pszNetworkAddress,
  544.                                      pszEndpoint,
  545.                                      pszOptions,
  546.                                      &pszStringBinding);
  547.     if (status) {
  548.         sprintf(pszFail, "RpcStringBindingCompose failed: (0x%x)nNetwork Address = %sn",
  549.                 status, pszNetworkAddress);
  550.         MessageBox(hWnd,
  551.                    pszFail,
  552.                    "RPC Runtime Error",
  553.                    MB_ICONEXCLAMATION);
  554.         return(status);
  555.     }
  556.     status = RpcBindingFromStringBinding(pszStringBinding,
  557.                                          &hYield);
  558.     if (status) {
  559.         sprintf(pszFail, "RpcBindingFromStringBinding failed: (0x%x)nString = %sn",
  560.                 status, pszStringBinding);
  561.         MessageBox(hWnd,
  562.                    pszFail,
  563.                    "RPC Runtime Error",
  564.                    MB_ICONEXCLAMATION);
  565.         return(status);
  566.     }
  567.     fBound = TRUE;  // bind successful; reset flag
  568.     return(status);
  569. }
  570. /**** end yieldc.c ****/