home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / oleaut / hello / hellctrl / hellctrl.cpp next >
C/C++ Source or Header  |  1996-06-12  |  10KB  |  339 lines

  1. /*************************************************************************
  2. **
  3. **    Automation Controller that uses vtable binding.
  4. **    Controls the HELLO automation object.
  5. **
  6. **    hellctrl.cpp
  7. **
  8. **
  9. **     Written by Microsoft Product Support Services, Windows Developer Support
  10. **    (c) Copyright Microsoft Corp. 1994 - 1996 All Rights Reserved
  11. **
  12. *************************************************************************/
  13. #define STRICT
  14.  
  15. #include <windows.h>
  16. #include <windowsx.h>
  17. #ifdef WIN16   
  18.   #include <ole2.h>
  19.   #include <compobj.h>    
  20.   #include <dispatch.h> 
  21.   #include <variant.h>
  22.   #include <olenls.h>
  23.   #include <commdlg.h>  
  24. #endif  
  25. #include <initguid.h>   
  26. #include "tlb.h" 
  27. #include "hellctrl.h"      
  28.  
  29. // Globals
  30. HINSTANCE g_hinst;                          // Instance of application
  31. HWND      g_hwnd;                           // Toplevel window handle
  32.  
  33. // String resource buffers
  34. TCHAR g_szTitle[STR_LEN];                    // Main window caption
  35. TCHAR g_szResult[STR_LEN];                   // "Result"
  36. TCHAR g_szError[STR_LEN];                    // "Error"
  37.  
  38. /*
  39.  * WinMain
  40.  *
  41.  * Purpose:
  42.  *  Main entry point of application. Should register the app class
  43.  *  if a previous instance has not done so and do any other one-time
  44.  *  initializations.
  45.  *
  46.  */
  47. int APIENTRY WinMain (HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpCmdLine, int nCmdShow)
  48. {
  49.    MSG msg;
  50.        
  51. #ifdef WIN16
  52.    //  It is recommended that all 16 bit OLE applications set
  53.    //  their message queue size to 96. This improves the capacity
  54.    //  and performance of OLE's LRPC mechanism.
  55.    int cMsg = 96;                  // Recommend msg queue size for OLE
  56.    while (cMsg && !SetMessageQueue(cMsg))  // take largest size we can get.
  57.        cMsg -= 8;
  58.    if (!cMsg)
  59.        return -1;  // ERROR: we got no message queue       
  60. #endif
  61.    
  62.    // Load string constants
  63.    LoadString(hinst, IDS_PROGNAME, g_szTitle, STR_LEN);
  64.    LoadString(hinst, IDS_RESULT, g_szResult, STR_LEN);
  65.    LoadString(hinst, IDS_ERROR, g_szError, STR_LEN);
  66.    
  67.    if (!hinstPrev)
  68.       if (!InitApplication(hinst))
  69.          return (FALSE);
  70.  
  71.    if(OleInitialize(NULL) != NOERROR)
  72.       return FALSE;
  73.       
  74.    if (!InitInstance(hinst, nCmdShow))
  75.       return (FALSE);
  76.  
  77.    while (GetMessage(&msg, NULL, NULL, NULL))
  78.    {
  79.       TranslateMessage(&msg);
  80.       DispatchMessage(&msg);
  81.    }
  82.    
  83.    OleUninitialize();
  84.    
  85.    return (msg.wParam); // Returns the value from PostQuitMessage
  86. }
  87.  
  88. /*
  89.  * InitApplication
  90.  *
  91.  * Purpose:
  92.  *  Registers window class
  93.  *
  94.  * Parameters:
  95.  *  hinst       hInstance of application
  96.  *
  97.  * Return Value:
  98.  *  TRUE if initialization succeeded, FALSE otherwise.
  99.  */
  100. BOOL InitApplication (HINSTANCE hinst)
  101. {
  102.    WNDCLASS wc;
  103.  
  104.    wc.style = CS_DBLCLKS;
  105.    wc.lpfnWndProc = MainWndProc;
  106.    wc.cbClsExtra = 0;
  107.    wc.cbWndExtra = 0;
  108.    wc.hInstance = hinst;
  109.    wc.hIcon = LoadIcon(hinst, TEXT("ControlIcon"));
  110.    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  111.    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  112.    wc.lpszMenuName = TEXT("ControlMenu");
  113.    wc.lpszClassName = TEXT("MainWndClass");
  114.      
  115.    return RegisterClass(&wc);
  116.  }
  117.  
  118. /*
  119.  * InitInstance
  120.  *
  121.  * Purpose:
  122.  *  Creates and shows main window
  123.  *
  124.  * Parameters:
  125.  *  hinst           hInstance of application
  126.  *  nCmdShow        specifies how window is to be shown
  127.  *
  128.  * Return Value:
  129.  *  TRUE if initialization succeeded, FALSE otherwise.
  130.  */
  131. BOOL InitInstance (HINSTANCE hinst, int nCmdShow)
  132. {
  133.   
  134.    g_hinst = hinst;
  135.    // Create Main Window
  136.    g_hwnd = CreateWindow(TEXT("MainWndClass"), g_szTitle,
  137.                        WS_OVERLAPPEDWINDOW,
  138.                        CW_USEDEFAULT, CW_USEDEFAULT,
  139.                        400, 200,
  140.                        NULL, NULL, hinst, NULL);
  141.    if (!g_hwnd)
  142.       return FALSE;
  143.    
  144.    ShowWindow(g_hwnd, nCmdShow);                  
  145.    UpdateWindow(g_hwnd);            
  146.    return TRUE;
  147. }
  148.  
  149. /*
  150.  * MainWndProc
  151.  *
  152.  * Purpose:
  153.  *  Window procedure for main window
  154.  *
  155.  */
  156. LRESULT CALLBACK MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  157. {
  158.    static IHello FAR* phello = NULL;    
  159.    HRESULT hr;
  160.    LPUNKNOWN punk;
  161.    
  162.    switch (msg)
  163.    {
  164.       case WM_COMMAND:
  165.          switch (wParam)
  166.          {
  167.             case IDM_CREATEHELLO:   
  168.                 // Create Hello object and QueryInterface for IHello interface.
  169.                 hr = CoCreateInstance(CLSID_Hello, NULL, CLSCTX_SERVER, 
  170.                      IID_IUnknown, (void FAR* FAR*)&punk);
  171.                 if (FAILED(hr))  
  172.                 {
  173.                     MessageBox(NULL, TEXT("CoCreateInstance"), g_szError, MB_OK); 
  174.                     return 0L;
  175.                 }                     
  176.                 hr = punk->QueryInterface(IID_IHello,  (void FAR* FAR*)&phello);   
  177.                 if (FAILED(hr))  
  178.                 {
  179.                     MessageBox(NULL, TEXT("QueryInterface(IID_IHello)"), g_szError, MB_OK);
  180.                     punk->Release(); 
  181.                     return 0L;
  182.                 }
  183.                 punk->Release();
  184.                 return 0L;
  185.                                
  186.             case IDM_SETVISIBLE:  
  187.                 // Set Visible property to TRUE
  188.                 hr = phello->put_Visible(TRUE);
  189.                 if (FAILED(hr))
  190.                     DisplayError(phello);
  191.                 return 0L;
  192.                 
  193.             case IDM_SETINVISIBLE:    
  194.                 // Set visible property to FALSE
  195.                 hr = phello->put_Visible(FALSE);
  196.                 if (FAILED(hr))
  197.                     DisplayError(phello);
  198.                 return 0L;
  199.                 
  200.             case IDM_GETHELLOMESSAGE:    
  201.             {   
  202.                 // Access Hello Message property and display it
  203.                 // in a MessageBox
  204.                 BSTR bstr = NULL;   // BSTR must be intialized before passing
  205.                                     // to get_HelloMessage.
  206.                 hr = phello->get_HelloMessage(&bstr);
  207.                 if (FAILED(hr))
  208.                     DisplayError(phello);
  209.                 else MessageBox(NULL, FROM_OLE_STRING(bstr), g_szResult, MB_OK); 
  210.                 
  211.                 // Caller is responsible for freeing parameters and return values.
  212.                 if (bstr)
  213.                     SysFreeString(bstr);
  214.                 return 0L;   
  215.             }
  216.               
  217.             case IDM_SAYHELLO:    
  218.                 // Invoke SayHello method
  219.                 hr = phello->SayHello();
  220.                 if (FAILED(hr))
  221.                     DisplayError(phello);
  222.                 return 0L;
  223.                 
  224.             case IDM_RELEASEHELLO:
  225.                 // Release the Hello object
  226.                 phello->Release();
  227.                 phello = NULL;
  228.                 return 0L;
  229.          }
  230.          break;
  231.          
  232.       case WM_INITMENUPOPUP:
  233.       {
  234.          HMENU hmenu = (HMENU)wParam;
  235.          
  236.          if (LOWORD(lParam) != 0)
  237.             return 0L;
  238.             
  239.          // Enable or gray the appropriate menu items. phello indicates if an automation object
  240.          //  is currently being controlled.   
  241.          EnableMenuItem(hmenu, IDM_CREATEHELLO,  MF_BYCOMMAND | (phello?MF_GRAYED:MF_ENABLED));
  242.          EnableMenuItem(hmenu, IDM_SETVISIBLE,   MF_BYCOMMAND | (phello?MF_ENABLED:MF_GRAYED)); 
  243.          EnableMenuItem(hmenu, IDM_SETINVISIBLE,   MF_BYCOMMAND | (phello?MF_ENABLED:MF_GRAYED));
  244.          EnableMenuItem(hmenu, IDM_GETHELLOMESSAGE,   MF_BYCOMMAND | (phello?MF_ENABLED:MF_GRAYED));
  245.          EnableMenuItem(hmenu, IDM_SAYHELLO,  MF_BYCOMMAND | (phello?MF_ENABLED:MF_GRAYED));
  246.          EnableMenuItem(hmenu, IDM_RELEASEHELLO, MF_BYCOMMAND | (phello?MF_ENABLED:MF_GRAYED));
  247.          return 0L;
  248.       }
  249.       
  250.       case WM_DESTROY:
  251.          if (phello)
  252.             phello->Release();                
  253.          PostQuitMessage(0);
  254.          break;
  255.  
  256.       default:                         
  257.          return DefWindowProc(hwnd, msg, wParam, lParam);
  258.    }
  259.    
  260.    return NULL;
  261. }
  262.  
  263. /*
  264.  * DisplayError
  265.  *
  266.  * Purpose:
  267.  *  Obtains Rich Error Information about the automation error from
  268.  *  the IErrorInfo interface.
  269.  *
  270.  */
  271. void DisplayError(IHello FAR* phello)
  272. {  
  273.    IErrorInfo FAR* perrinfo;    
  274.    BSTR bstrDesc;
  275.    HRESULT hr;
  276.    ISupportErrorInfo FAR* psupporterrinfo;  
  277.  
  278.    hr = phello->QueryInterface(IID_ISupportErrorInfo, (LPVOID FAR*)&psupporterrinfo);
  279.    if (FAILED(hr)) 
  280.    {
  281.       MessageBox(NULL, TEXT("QueryInterface(IID_ISupportErrorInfo)"), g_szError, MB_OK);
  282.       return;
  283.    }
  284.    
  285.    hr = psupporterrinfo->InterfaceSupportsErrorInfo(IID_IHello);   
  286.    if (hr != NOERROR)
  287.    {   
  288.        psupporterrinfo->Release();
  289.        return;
  290.    }
  291.    psupporterrinfo->Release();
  292.   
  293.    // In this example only the error description is obtained and displayed. 
  294.    // See the IErrorInfo interface for other information that is available. 
  295.    hr = GetErrorInfo(0, &perrinfo); 
  296.    if (FAILED(hr))
  297.        return;   
  298.    hr = perrinfo->GetDescription(&bstrDesc);
  299.    if (FAILED(hr)) 
  300.    {
  301.        perrinfo->Release(); 
  302.        return;
  303.    }  
  304.    
  305.    MessageBox(NULL, FROM_OLE_STRING(bstrDesc), g_szError, MB_OK);   
  306.    SysFreeString(bstrDesc);
  307. }
  308.  
  309. /*
  310.  * Quick & Dirty ANSI/Unicode conversion routines. These routines use a static
  311.  * buffer of fixed size to hold the converted string. Consequently these
  312.  * routines are limited to strings of size STRCONVERT_MAXLEN. Also the same
  313.  * buffer is reused when the routine is called a second time. So make sure
  314.  * that the converted string is used before the conversion routine is called
  315.  * again
  316.  */
  317. #ifdef WIN32
  318.  
  319. #ifndef UNICODE
  320. char* ConvertToAnsi(OLECHAR FAR* szW)
  321. {
  322.   static char achA[STRCONVERT_MAXLEN]; 
  323.   
  324.   WideCharToMultiByte(CP_ACP, 0, szW, -1, achA, STRCONVERT_MAXLEN, NULL, NULL);  
  325.   return achA; 
  326.  
  327. OLECHAR* ConvertToUnicode(char FAR* szA)
  328. {
  329.   static OLECHAR achW[STRCONVERT_MAXLEN]; 
  330.  
  331.   MultiByteToWideChar(CP_ACP, 0, szA, -1, achW, STRCONVERT_MAXLEN);  
  332.   return achW; 
  333. }
  334. #endif
  335.  
  336. #endif   
  337.    
  338.