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

Windows编程

开发平台:

Visual C++

  1. /*************************************************************************
  2. **
  3. **  This is a part of the Microsoft Source Code Samples.
  4. **
  5. **  Copyright (C) 1992-1997 Microsoft Corporation. All rights reserved.
  6. **
  7. **  This source code is only intended as a supplement to Microsoft Development
  8. **  Tools and/or WinHelp documentation.  See these sources for detailed
  9. **  information regarding the Microsoft samples programs.
  10. **
  11. **  OLE Automation Hello 2.0 Application.
  12. **
  13. **  hello.cpp
  14. **
  15. **  CHello implementation
  16. **
  17. **  Written by Microsoft Product Support Services, Windows Developer Support
  18. **
  19. *************************************************************************/
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #ifdef WIN16   
  23.   #include <ole2.h>
  24.   #include <compobj.h>    
  25.   #include <dispatch.h> 
  26.   #include <variant.h>
  27.   #include <olenls.h>  
  28. #endif 
  29. #include "hello.h"
  30. /*
  31.  * CHello::Create
  32.  *
  33.  * Purpose:
  34.  *  Creates an instance of the Hello Application object and initializes it.
  35.  *
  36.  * Parameters:
  37.  *  hinst      HINSTANCE of application.
  38.  *  lpszHelloMessage Initial Hello message. 
  39.  *  pphello    Returns Hello automation object.
  40.  *
  41.  * Return Value:
  42.  *  HRESULT
  43.  *
  44.  */
  45. HRESULT 
  46. CHello::Create(HINSTANCE hinst, LPTSTR lpszHelloMessage, CHello FAR* FAR* pphello) 
  47. {   
  48.     TCHAR ach[STR_LEN];   
  49.     TCHAR achFullName[260];
  50.     HRESULT hr;
  51.     CHello FAR* phello = NULL;   
  52.     HWND hwnd;
  53.      
  54.     *pphello = NULL;
  55.     
  56.     // Create Hello Application object
  57.     phello = new CHello();
  58.     if (phello == NULL)
  59.         goto error;
  60.    
  61.     // Create Main Window
  62.     hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_MAINWINDOW), NULL, NULL);
  63.     if (!hwnd)
  64.     {
  65.         hr = E_OUTOFMEMORY;    
  66.         goto error;
  67.     }  
  68.      
  69.     phello->m_cRef = 0;
  70.     phello->m_bVisible = FALSE;
  71.     phello->m_hwnd = hwnd;     
  72.     phello->m_hinst = hinst;
  73.     
  74.     // FullName
  75.     GetModuleFileName(hinst, achFullName, sizeof(achFullName)); 
  76.     phello->m_bstrFullName = SysAllocString(TO_OLE_STRING(achFullName));
  77.     if (NULL == phello->m_bstrFullName)
  78.     {
  79.         hr = E_OUTOFMEMORY;    
  80.         goto error;
  81.     }   
  82.     // Name
  83.     LoadString(hinst, IDS_Name, ach, sizeof(ach));  
  84.     phello->m_bstrName = SysAllocString(TO_OLE_STRING(ach));
  85.     if (NULL == phello->m_bstrName)
  86.     {
  87.         hr = E_OUTOFMEMORY;    
  88.         goto error;
  89.     } 
  90.     // ProgID 
  91.     LoadString(hinst, IDS_ProgID, ach, sizeof(ach));  
  92.     phello->m_bstrProgID = SysAllocString(TO_OLE_STRING(ach));
  93.     if (NULL == phello->m_bstrProgID)
  94.     {
  95.         hr = E_OUTOFMEMORY;    
  96.         goto error;
  97.     }   
  98.     // Hello Message
  99.     phello->m_bstrHelloMsg = SysAllocString(TO_OLE_STRING(lpszHelloMessage));
  100.     if (NULL == phello->m_bstrHelloMsg)
  101.     {
  102.         hr = E_OUTOFMEMORY;    
  103.         goto error;
  104.     }
  105.     
  106.     // Load type information from type library. If required, notify user on failure. 
  107.     hr = LoadTypeInfo(&phello->m_ptinfo, IID_IHello);
  108.     if (FAILED(hr)) 
  109.     {
  110.         
  111.         LoadString(hinst, IDS_ErrorLoadingTypeLib, ach, sizeof(ach));
  112.         MessageBox(NULL, ach, FROM_OLE_STRING(phello->m_bstrName), MB_OK);
  113.         goto error;
  114.     }
  115.          
  116.     *pphello = phello;
  117.     return NOERROR;
  118.     
  119. error:                        
  120.     if (phello == NULL) return E_OUTOFMEMORY;    
  121.     if (phello->m_bstrFullName) SysFreeString(phello->m_bstrFullName);  
  122.     if (phello->m_bstrName) SysFreeString(phello->m_bstrName); 
  123.     if (phello->m_bstrProgID) SysFreeString(phello->m_bstrProgID);                     
  124.     if (phello->m_bstrHelloMsg) SysFreeString(phello->m_bstrHelloMsg);      
  125.     if (phello->m_ptinfo) phello->m_ptinfo->Release();
  126.     
  127.     // Set to NULL to prevent destructor from attempting to free again
  128.     phello->m_bstrFullName = NULL;
  129.     phello->m_bstrName = NULL;
  130.     phello->m_bstrProgID = NULL;
  131.     phello->m_bstrHelloMsg = NULL;
  132.     phello->m_ptinfo = NULL;
  133.     
  134.     delete phello;
  135.     return hr;
  136. }
  137. /*
  138.  * CHello::CHello
  139.  *
  140.  * Purpose:
  141.  *  Constructor for CHello object. Initializes members to NULL.
  142.  *
  143.  */
  144. #pragma warning (disable : 4355)
  145. CHello::CHello() : m_SupportErrorInfo(this, IID_IHello)
  146. #pragma warning (default : 4355)
  147. {   
  148.     extern ULONG g_cObj;
  149.      
  150.     m_hwnd = NULL;
  151.     m_bstrFullName = NULL;
  152.     m_bstrName = NULL;
  153.     m_bstrProgID = NULL;
  154.     m_bstrHelloMsg = NULL;
  155.     m_ptinfo = NULL; 
  156.     m_bVisible = 0;
  157. }
  158. /*
  159.  * CHello::~CHello
  160.  *
  161.  * Purpose:
  162.  *  Destructor for CHello object. 
  163.  *
  164.  */
  165. CHello::~CHello()
  166.      extern ULONG g_cObj;
  167.      
  168.      if (m_bstrFullName) SysFreeString(m_bstrFullName);
  169.      if (m_bstrName) SysFreeString(m_bstrName);
  170.      if (m_bstrProgID) SysFreeString(m_bstrProgID);
  171.      if (m_bstrHelloMsg) SysFreeString(m_bstrHelloMsg);          
  172.      if (m_ptinfo) m_ptinfo->Release();
  173.      if (IsWindow(m_hwnd)) DestroyWindow(m_hwnd);
  174. }
  175. /*
  176.  * CHello::QueryInterface, AddRef, Release
  177.  *
  178.  * Purpose:
  179.  *  Implements IUnknown::QueryInterface, AddRef, Release
  180.  *
  181.  */
  182. STDMETHODIMP
  183. CHello::QueryInterface(REFIID iid, void FAR* FAR* ppv) 
  184. {   
  185.     *ppv = NULL;
  186.     
  187.     if (iid == IID_IUnknown || iid == IID_IDispatch || iid == IID_IHello  ) 
  188.         *ppv = this;   
  189.     else if (iid == IID_ISupportErrorInfo)
  190.         *ppv = &m_SupportErrorInfo;
  191.     else return E_NOINTERFACE; 
  192.     AddRef();
  193.     return NOERROR;    
  194. }
  195. STDMETHODIMP_(ULONG)
  196. CHello::AddRef(void)
  197. {
  198. #ifdef _DEBUG  
  199.     TCHAR ach[50];
  200.     wsprintf(ach, TEXT("AddRef: Ref = %ld, Hellorn"), m_cRef+1); 
  201.     OutputDebugString(ach); 
  202. #endif  
  203.     return ++m_cRef;
  204. }
  205. STDMETHODIMP_(ULONG)
  206. CHello::Release(void)
  207. {
  208. #ifdef _DEBUG  
  209.     TCHAR ach[50];
  210.     wsprintf(ach, TEXT("Release: Ref = %ld, Hellorn"), m_cRef-1); 
  211.     OutputDebugString(ach);   
  212. #endif
  213.     if(--m_cRef == 0)
  214.     {
  215.         delete this;
  216.         return 0;
  217.     }
  218.     return m_cRef;
  219. }
  220. /*
  221.  * CHello::GetTypeInfoCount
  222.  *
  223.  * Purpose:
  224.  *  Implements IDispatch::GetTypeInfoCount.
  225.  *
  226.  */
  227. STDMETHODIMP
  228. CHello::GetTypeInfoCount(UINT FAR* pctinfo)
  229. {
  230.     *pctinfo = 1;
  231.     return NOERROR;
  232. }
  233. /*
  234.  * CHello::GetTypeInfo
  235.  *
  236.  * Purpose:
  237.  *  Implements IDispatch::GetTypeInfo. 
  238.  *
  239.  */
  240. STDMETHODIMP
  241. CHello::GetTypeInfo(
  242.       UINT itinfo,
  243.       LCID lcid,
  244.       ITypeInfo FAR* FAR* pptinfo)
  245. {    
  246.     *pptinfo = NULL;
  247.      
  248.     if(itinfo != 0)
  249.         return DISP_E_BADINDEX;
  250.     
  251.     m_ptinfo->AddRef(); 
  252.     *pptinfo = m_ptinfo;
  253.     
  254.     return NOERROR;
  255. }
  256. /*
  257.  * CHello::GetIDsOfNames
  258.  *
  259.  * Purpose:
  260.  *  Implements IDispatch::GetIDsOfNames.  The standard implementation, DispGetIDsOfNames,
  261.  *  is used.
  262.  *
  263.  */
  264. STDMETHODIMP 
  265. CHello::GetIDsOfNames(
  266.       REFIID riid,
  267.       OLECHAR FAR* FAR* rgszNames,
  268.       UINT cNames,
  269.       LCID lcid,
  270.       DISPID FAR* rgdispid)
  271. {
  272.     return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
  273. }
  274. /*
  275.  * CHello::Invoke
  276.  *
  277.  * Purpose:
  278.  *  Implements IDispatch::Invoke.  The standard implementation, DispInvoke,
  279.  *  is used.
  280.  *
  281.  */
  282. STDMETHODIMP
  283. CHello::Invoke(
  284.       DISPID dispidMember,
  285.       REFIID riid,
  286.       LCID lcid,
  287.       WORD wFlags,
  288.       DISPPARAMS FAR* pdispparams,
  289.       VARIANT FAR* pvarResult,
  290.       EXCEPINFO FAR* pexcepinfo,
  291.       UINT FAR* puArgErr)
  292. {        
  293.     return DispInvoke(
  294.         this, m_ptinfo,
  295.         dispidMember, wFlags, pdispparams,
  296.         pvarResult, pexcepinfo, puArgErr); 
  297. }
  298. /*
  299.  * CHello::put_HelloMessage, get_HelloMessage, SayHello
  300.  *
  301.  * Purpose:
  302.  *  Implements the standard Application, FullName, Name, Parent & Visible properties
  303.  *  and the Quit method. 
  304.  *
  305.  */
  306. STDMETHODIMP 
  307. CHello::get_Application(IHello FAR* FAR* ppHello)
  308. {
  309.     HRESULT hr;
  310.     
  311.     *ppHello = NULL;
  312.     
  313.     hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppHello);  
  314.     if (FAILED(hr))
  315.         return RaiseException(IDS_Unexpected, IID_IHello); 
  316.     return hr;
  317. }
  318. STDMETHODIMP
  319. CHello::get_FullName(BSTR FAR* pbstr)
  320. {
  321.     *pbstr = SysAllocString(m_bstrFullName);   
  322.     return NOERROR;
  323. }
  324. STDMETHODIMP
  325. CHello::get_Name(BSTR FAR* pbstr)
  326. {
  327.     *pbstr = SysAllocString(m_bstrName);   
  328.     return NOERROR;
  329. }
  330. STDMETHODIMP
  331. CHello::get_Parent(IHello FAR* FAR* ppHello)
  332. {
  333.     HRESULT hr;
  334.     
  335.     *ppHello = NULL;
  336.     
  337.     hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppHello);   
  338.     if (FAILED(hr))
  339.         return RaiseException(IDS_Unexpected, IID_IHello); 
  340.     return NOERROR;
  341. }
  342. STDMETHODIMP
  343. CHello::put_Visible(VARIANT_BOOL bVisible)
  344. {
  345.     ShowWindow(bVisible ? SW_SHOW : SW_HIDE);  
  346.     return NOERROR;
  347. }
  348. STDMETHODIMP
  349. CHello::get_Visible(VARIANT_BOOL FAR* pbool)
  350. {
  351.     *pbool =  m_bVisible;  
  352.     return NOERROR;
  353. }
  354. STDMETHODIMP
  355. CHello::Quit() 
  356. {
  357.     // CoDisconnectObject has no effect for an inproc server.  So the controller
  358.     // will GP fault if it attempts to access the object (including calling IUnknown::Release())
  359.     // after Quit has been called. For a local server, CoDisconnectObject will disconnect
  360.     // the object from external connections. So the controller will get an RPC error if
  361.     // it accesses the object after calling Quit and controller will not GP fault. 
  362.     CoDisconnectObject((LPUNKNOWN)this, 0);  
  363.     PostMessage(m_hwnd, WM_CLOSE, 0, 0L);
  364.     return NOERROR;           
  365. /*
  366.  * CHello::put_HelloMessage, get_HelloMessage, SayHello
  367.  *
  368.  * Purpose:
  369.  *  Implements the HelloMessage property and the SayHello method.
  370.  *
  371.  */    
  372. STDMETHODIMP
  373. CHello::put_HelloMessage(BSTR bstrMessage)
  374. {
  375.     SysReAllocString(&m_bstrHelloMsg, bstrMessage);   
  376.     return NOERROR; 
  377. }
  378. STDMETHODIMP
  379. CHello::get_HelloMessage(BSTR FAR* pbstrMessage)
  380. {   
  381.     *pbstrMessage = SysAllocString(m_bstrHelloMsg);
  382.     return NOERROR; 
  383. }
  384. STDMETHODIMP
  385. CHello::SayHello()
  386. {    
  387.     SetDlgItemText(m_hwnd, IDC_HELLODISPLAY, FROM_OLE_STRING(m_bstrHelloMsg));       
  388.     return NOERROR;
  389. }
  390. STDMETHODIMP_(void)
  391. CHello::ShowWindow(int nCmdShow)
  392. {   
  393.     // Return if curently hidden and asked to hide or currently visible
  394.     // and asked to show.
  395.     if ((!m_bVisible && nCmdShow == SW_HIDE) || (m_bVisible && nCmdShow != SW_HIDE))
  396.         return; 
  397.     
  398.     m_bVisible = (nCmdShow == SW_HIDE) ? FALSE : TRUE;
  399.     
  400.     // The Automation object shutdown behavior is as follows:
  401.     // 1. If the object application is visible, it shuts down only in response to an
  402.     // explicit user command (File/Exit) or it's programmatic equivalent (for example
  403.     // the Quit method of the Application object).
  404.     // 2. If the object application is not visible, it goes away when it's last
  405.     // object is released.   
  406.     //   
  407.     // CoLockObjectExternal can be used to increment the ref count of the application object
  408.     // when it is visible. This will implement shutdown behavior 1. When the application
  409.     // goes invisible, CoLockObjectExternal is used to decrement the ref count. This will
  410.     // implement shutdown behavior 2.
  411.     
  412.     if (m_bVisible)
  413.         CoLockObjectExternal(this, TRUE /*fLock*/, TRUE/*ignored when fLock==TRUE*/);
  414.     else CoLockObjectExternal(this, FALSE/*fLock*/, TRUE/*fLastLockReleases*/);  
  415.     ::ShowWindow (m_hwnd, nCmdShow);
  416. }
  417. /*
  418.  * ISupportErrorInfo implementation
  419.  *
  420.  */
  421. CSupportErrorInfo::CSupportErrorInfo(IUnknown FAR* punkObject, REFIID riid)
  422. {
  423.     m_punkObject = punkObject; 
  424.     m_iid = riid;
  425. }         
  426. STDMETHODIMP
  427. CSupportErrorInfo::QueryInterface(REFIID iid, void FAR* FAR* ppv) 
  428. {   
  429.     return m_punkObject->QueryInterface(iid, ppv);    
  430. }
  431. STDMETHODIMP_(ULONG)
  432. CSupportErrorInfo::AddRef(void)
  433. {
  434.     return m_punkObject->AddRef();
  435. }
  436. STDMETHODIMP_(ULONG)
  437. CSupportErrorInfo::Release(void)
  438. {
  439.     return m_punkObject->Release();
  440. STDMETHODIMP
  441. CSupportErrorInfo::InterfaceSupportsErrorInfo(REFIID riid)  
  442. {
  443.     return (riid == m_iid) ? NOERROR : S_FALSE;
  444. }