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

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 Lines Object.
  12. **
  13. **  app.cpp
  14. **
  15. **  CApplication 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 "lines.h"  
  30. /*
  31.  * CApplication::Create
  32.  *
  33.  * Purpose:
  34.  *  Creates an instance of the Application automation object and initializes it.
  35.  *
  36.  * Parameters:       
  37.  *  hinst            HINSTANCE of application.
  38.  *  ppApplication    Returns Application automation object.
  39.  *
  40.  * Return Value:
  41.  *  HRESULT
  42.  *
  43.  */
  44. HRESULT
  45. CApplication::Create(HINSTANCE hinst, CApplication FAR* FAR* ppApplication ) 
  46. {   
  47.     TCHAR ach[STR_LEN];   
  48.     TCHAR achFullName[260];
  49.     HRESULT hr;
  50.     CApplication FAR* pApplication = NULL;  
  51.     HWND hwnd;
  52.      
  53.     *ppApplication = NULL;
  54.     
  55.     // Create application object.
  56.     pApplication = new CApplication();
  57.     if (pApplication == NULL)
  58.     {
  59.         hr = E_OUTOFMEMORY; 
  60.         goto error;
  61.     }
  62.     
  63.     LoadString(hinst, IDS_Name, ach, sizeof(ach));
  64.     hwnd = CreateWindow(TEXT("MainWndClass"), ach,
  65.                        WS_OVERLAPPEDWINDOW,
  66.                        CW_USEDEFAULT, CW_USEDEFAULT,
  67.                        650, 650,
  68.                        NULL, NULL, hinst, NULL);
  69.     if (!hwnd)
  70.     {
  71.        hr = E_OUTOFMEMORY;  
  72.        goto error;
  73.     }  
  74.     pApplication->m_hwnd = hwnd;
  75.     pApplication->m_hinst = hinst;
  76.     
  77.     // Set name and fullname of application.  
  78.     pApplication->m_bstrName = SysAllocString(TO_OLE_STRING(ach));
  79.     if (NULL == pApplication->m_bstrName)
  80.     {
  81.         hr = E_OUTOFMEMORY;    
  82.         goto error;
  83.     } 
  84.     GetModuleFileName(hinst, achFullName, sizeof(achFullName));
  85.     pApplication->m_bstrFullName = SysAllocString(TO_OLE_STRING(achFullName));
  86.     if (NULL == pApplication->m_bstrFullName)
  87.     {
  88.         hr = E_OUTOFMEMORY;    
  89.         goto error;
  90.     }
  91.     // ProgID 
  92.     LoadString(hinst, IDS_ProgID, ach, sizeof(ach));  
  93.     pApplication->m_bstrProgID = SysAllocString(TO_OLE_STRING(ach));
  94.     if (NULL == pApplication->m_bstrProgID)
  95.     {
  96.         hr = E_OUTOFMEMORY;    
  97.         goto error;
  98.     }      
  99.     
  100.     // Load type information for the application object from type library.
  101.     // If required, notify user on failure. 
  102.     hr = LoadTypeInfo(&pApplication->m_ptinfo, IID_IApplication);
  103.     if (FAILED(hr)) 
  104.     {       
  105.         LoadString(hinst, IDS_ErrorLoadingTypeLib, ach, sizeof(ach));
  106.         MessageBox(NULL, ach, FROM_OLE_STRING(pApplication->m_bstrName), MB_OK);
  107.         goto error;
  108.     }
  109.         
  110.     // Create Pane    
  111.     hr = CPane::Create(hwnd, &pApplication->m_pPane);
  112.     if (FAILED(hr))
  113.        goto error;    
  114.     pApplication->m_pPane->AddRef();    
  115.     *ppApplication = pApplication;
  116.     return NOERROR;
  117.     
  118. error:                        
  119.     if (pApplication == NULL)
  120.         return E_OUTOFMEMORY; 
  121.     
  122.     if (pApplication->m_bstrFullName)
  123.         SysFreeString(pApplication->m_bstrFullName);  
  124.     if (pApplication->m_bstrName)
  125.         SysFreeString(pApplication->m_bstrName);
  126.     if (pApplication->m_bstrProgID) 
  127.         SysFreeString(pApplication->m_bstrProgID);                       
  128.     if (pApplication->m_ptinfo)
  129.         pApplication->m_ptinfo->Release();        
  130.     if (pApplication->m_pPane)
  131.         pApplication->m_pPane->Release();
  132.     
  133.     // Set to NULL to prevent destructor from attempting to free again
  134.     pApplication->m_bstrFullName = NULL;
  135.     pApplication->m_bstrName = NULL;
  136.         pApplication->m_bstrProgID = NULL;
  137.     pApplication->m_ptinfo = NULL;
  138.     pApplication->m_pPane = NULL;
  139.     
  140.     delete pApplication;
  141.     return hr;
  142. }
  143. /*
  144.  * CApplication::CApplication
  145.  *
  146.  * Purpose:
  147.  *  Constructor for CApplication object. Initializes members to NULL.
  148.  *
  149.  */
  150. #pragma warning (disable : 4355)
  151. CApplication::CApplication() : m_SupportErrorInfo(this, IID_IApplication)
  152. #pragma warning (default : 4355)
  153. {   
  154.     extern ULONG g_cObj;
  155.      
  156.     m_hwnd = NULL;
  157.     m_bstrFullName = NULL;
  158.     m_bstrName = NULL;
  159.     m_bstrProgID = NULL;
  160.     m_ptinfo = NULL;
  161.     m_pPane = NULL;
  162.     m_cRef = 0;   
  163.     m_bVisible = 0;
  164.     m_bUserClosing = FALSE;
  165. }
  166. /*
  167.  * CApplication::~CApplication
  168.  *
  169.  * Purpose:
  170.  *  Destructor for CApplication object. Frees Application message BSTR and default
  171.  *  IDispatch implementation. Closes the aplication.
  172.  *
  173.  */
  174. CApplication::~CApplication()
  175.      extern ULONG g_cObj;
  176.      
  177.      if (m_bstrFullName) SysFreeString(m_bstrFullName);
  178.      if (m_bstrName) SysFreeString(m_bstrName);
  179.      if (m_bstrProgID) SysFreeString(m_bstrProgID);          
  180.      if (m_ptinfo) m_ptinfo->Release();  
  181.      if (m_pPane) m_pPane->Release();
  182.      if (!m_bUserClosing && IsWindow(m_hwnd)) DestroyWindow(m_hwnd);     
  183. }
  184. /*
  185.  * CApplication::QueryInterface, AddRef, Release
  186.  *
  187.  * Purpose:
  188.  *  Implements IUnknown::QueryInterface, AddRef, Release
  189.  *
  190.  */
  191. STDMETHODIMP
  192. CApplication::QueryInterface(REFIID iid, void FAR* FAR* ppv) 
  193. {   
  194.     *ppv = NULL;
  195.     
  196.     if (iid == IID_IUnknown || iid == IID_IDispatch || iid == IID_IApplication)
  197.         *ppv = this; 
  198.     else if (iid == IID_ISupportErrorInfo)
  199.         *ppv = &m_SupportErrorInfo;
  200.     else return E_NOINTERFACE; 
  201.     AddRef();
  202.     return NOERROR;    
  203. }
  204. STDMETHODIMP_(ULONG)
  205. CApplication::AddRef(void)
  206. {    
  207. #ifdef _DEBUG  
  208.     TCHAR ach[50];
  209.     wsprintf(ach, TEXT("Ref = %ld, Apprn"), m_cRef+1); 
  210.     OutputDebugString(ach); 
  211. #endif  
  212.     return ++m_cRef;
  213. }
  214. STDMETHODIMP_(ULONG)
  215. CApplication::Release(void)
  216. {
  217. #ifdef _DEBUG  
  218.     TCHAR ach[50];
  219.     wsprintf(ach, TEXT("Ref = %ld, Apprn"), m_cRef-1); 
  220.     OutputDebugString(ach);   
  221. #endif
  222.     
  223.     if(--m_cRef == 0)
  224.     {
  225.         delete this;
  226.         return 0;
  227.     }
  228.     return m_cRef;
  229. }
  230. /*
  231.  * CApplication::GetTypeInfoCount
  232.  *
  233.  * Purpose:
  234.  *  Implements IDispatch::GetTypeInfoCount.
  235.  *
  236.  */
  237. STDMETHODIMP
  238. CApplication::GetTypeInfoCount(UINT FAR* pctinfo)
  239. {
  240.     *pctinfo = 1;
  241.     return NOERROR;
  242. }
  243. /*
  244.  * CApplication::GetTypeInfo
  245.  *
  246.  * Purpose:
  247.  *  Implements IDispatch::GetTypeInfo. 
  248.  *
  249.  */
  250. STDMETHODIMP
  251. CApplication::GetTypeInfo(
  252.       UINT itinfo,
  253.       LCID lcid,
  254.       ITypeInfo FAR* FAR* pptinfo)
  255. {    
  256.     *pptinfo = NULL;
  257.      
  258.     if(itinfo != 0)
  259.         return DISP_E_BADINDEX;
  260.     
  261.     m_ptinfo->AddRef(); 
  262.     *pptinfo = m_ptinfo;
  263.     
  264.     return NOERROR;
  265. }
  266. /*
  267.  * CApplication::GetIDsOfNames
  268.  *
  269.  * Purpose:
  270.  *  Implements IDispatch::GetIDsOfNames.  The standard implementation, DispGetIDsOfNames,
  271.  *  is used.
  272.  *
  273.  */
  274. STDMETHODIMP 
  275. CApplication::GetIDsOfNames(
  276.       REFIID riid,
  277.       OLECHAR FAR* FAR* rgszNames,
  278.       UINT cNames,
  279.       LCID lcid,
  280.       DISPID FAR* rgdispid)
  281. {
  282.     return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
  283. }
  284. /*
  285.  * CApplication::Invoke
  286.  *
  287.  * Purpose:
  288.  *  Implements IDispatch::Invoke.  The standard implementation, DispInvoke,
  289.  *  is used.
  290.  *
  291.  */
  292. STDMETHODIMP
  293. CApplication::Invoke(
  294.       DISPID dispidMember,
  295.       REFIID riid,
  296.       LCID lcid,
  297.       WORD wFlags,
  298.       DISPPARAMS FAR* pdispparams,
  299.       VARIANT FAR* pvarResult,
  300.       EXCEPINFO FAR* pexcepinfo,
  301.       UINT FAR* puArgErr)
  302. {  
  303.    return DispInvoke(
  304.         this, m_ptinfo,
  305.         dispidMember, wFlags, pdispparams,
  306.         pvarResult, pexcepinfo, puArgErr);   
  307. }
  308. /*
  309.  * CApplication::get_Application, get_FullName, get_Name, get_Parent, get_Visible, put_Visible, Quit 
  310.  *
  311.  * Purpose:
  312.  *  Implements the standard Application, FullName, Name, Parent & Visible properties
  313.  *  and the Quit method. 
  314.  *
  315.  */
  316. STDMETHODIMP
  317. CApplication::get_Application(IApplication FAR* FAR* ppApplication)
  318. {
  319.     HRESULT hr;
  320.     
  321.     hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppApplication); 
  322.     if (FAILED(hr))
  323.         return RaiseException(IDS_Unexpected, IID_IApplication); 
  324.     return NOERROR;
  325. }
  326. STDMETHODIMP
  327. CApplication::get_FullName(BSTR FAR* pbstr)
  328. {
  329.     *pbstr = SysAllocString(m_bstrFullName);   
  330.     return NOERROR;
  331. }
  332. STDMETHODIMP
  333. CApplication::get_Name(BSTR FAR* pbstr)
  334. {
  335.     *pbstr = SysAllocString(m_bstrName); 
  336.     return NOERROR; 
  337. }
  338. STDMETHODIMP
  339. CApplication::get_Parent(IApplication FAR* FAR* ppApplication)      
  340. {
  341.     HRESULT hr;
  342.     
  343.     hr = QueryInterface(IID_IDispatch, (void FAR* FAR*)ppApplication); 
  344.     if (FAILED(hr))
  345.         return RaiseException(IDS_Unexpected, IID_IApplication); 
  346.     return NOERROR;
  347. }
  348. STDMETHODIMP
  349. CApplication::put_Visible(VARIANT_BOOL bVisible)
  350. {
  351.     ShowWindow(bVisible ? SW_SHOW : SW_HIDE);  
  352.     return NOERROR;
  353. STDMETHODIMP
  354. CApplication::get_Visible(VARIANT_BOOL FAR* pbVisible)
  355. {
  356.     *pbVisible = m_bVisible;     
  357.     return NOERROR;
  358. }
  359. STDMETHODIMP
  360. CApplication::Quit()
  361. {
  362.     // CoDisconnectObject has no effect for an inproc server.  So the controller
  363.     // will GP fault if it attempts to access the object (including calling IUnknown::Release())
  364.     // after Quit has been called. For a local server, CoDisconnectObject will disconnect
  365.     // the object from external connections. So the controller will get an RPC error if
  366.     // it access the object after calling Quit. The controller will not GP fault in this case. 
  367.     CoDisconnectObject((LPUNKNOWN)this, 0);  
  368.     PostMessage(m_hwnd, WM_CLOSE, 0, 0L);
  369.     return NOERROR;                                     
  370. /*
  371.  * CApplication::get_Pane
  372.  *
  373.  * Purpose:
  374.  *  Returns pane object.
  375.  *
  376.  */      
  377. STDMETHODIMP
  378. CApplication::get_Pane(IPane FAR* FAR* ppPane)
  379. {
  380.     HRESULT hr;
  381.     
  382.     hr = m_pPane->QueryInterface(IID_IDispatch, (void FAR* FAR*)ppPane); 
  383.     if (FAILED(hr))
  384.         return RaiseException(IDS_Unexpected, IID_IApplication); 
  385.     return NOERROR;
  386. }
  387. /*
  388.  * CApplication::CreateLine
  389.  *
  390.  * Purpose:
  391.  *  Returns a newly created line object with no start or end point.
  392.  *
  393.  */  
  394. STDMETHODIMP
  395. CApplication::CreateLine(ILine FAR* FAR* ppLine)
  396. {
  397.     CLine FAR* pline = NULL;
  398.     HRESULT hr;
  399.     
  400.     // Create new item and QI for IDispatch   
  401.     hr = CLine::Create(&pline);
  402.     if (FAILED(hr)) 
  403.         {hr = RaiseException(IDS_OutOfMemory, IID_IApplication); goto error;} 
  404.               
  405.     hr = pline->QueryInterface(IID_IDispatch, (void FAR* FAR*)ppLine); 
  406.     if (FAILED(hr)) 
  407.         {hr = RaiseException(IDS_Unexpected, IID_IApplication); goto error;}
  408.     return NOERROR;
  409.     
  410. error: 
  411.     if (pline)
  412.         delete pline;       
  413.     return hr;     
  414. }
  415. /*
  416.  * CApplication::CreateLine
  417.  *
  418.  * Purpose:
  419.  *  Returns a newly created point object intialized to (0,0).
  420.  *
  421.  */ 
  422. STDMETHODIMP
  423. CApplication::CreatePoint(IPoint FAR* FAR* ppPoint)
  424. {
  425.     CPoint FAR* ppoint = NULL;
  426.     HRESULT hr;
  427.     
  428.     // Create new item and QI for IDispatch   
  429.     hr = CPoint::Create(&ppoint);
  430.     if (FAILED(hr))
  431.         {hr = RaiseException(IDS_OutOfMemory, IID_IApplication); goto error;}          
  432.         
  433.     hr = ppoint->QueryInterface(IID_IDispatch, (void FAR* FAR*)ppPoint); 
  434.     if (FAILED(hr))
  435.         {hr = RaiseException(IDS_Unexpected, IID_IApplication); goto error;}
  436.     return NOERROR;
  437.     
  438. error: 
  439.     if (ppoint)
  440.         delete ppoint;        
  441.     return hr;     
  442. }   
  443. /* 
  444.  *
  445.  * The following methods are not exposed through Automation
  446.  *
  447.  */
  448. STDMETHODIMP_(void)
  449. CApplication::Draw()
  450. {
  451.    m_pPane->Draw();
  452. }
  453. /*
  454.  * CApplication::OnSize
  455.  *
  456.  * Purpose:
  457.  *  Called when application window receives WM_SIZE.
  458.  *
  459.  */ 
  460. STDMETHODIMP_(void)
  461. CApplication::OnSize(unsigned int nWidth, unsigned int nHeight) 
  462. {
  463.    m_pPane->OnSize(nWidth, nHeight);
  464. STDMETHODIMP_(void)
  465. CApplication::ShowWindow(int nCmdShow)
  466. {   
  467.     // Return if curently hidden and asked to hide or currently visible
  468.     // and asked to show.
  469.     if ((!m_bVisible && nCmdShow == SW_HIDE) || (m_bVisible && nCmdShow != SW_HIDE))
  470.         return; 
  471.     
  472.     m_bVisible = (nCmdShow == SW_HIDE) ? FALSE : TRUE;
  473.     
  474.     // The Automation object shutdown behavior is as follows:
  475.     // 1. If the object application is visible, it shuts down only in response to an
  476.     // explicit user command (File/Exit) or it's programmatic equivalent (for example
  477.     // the Quit method of the Application object).
  478.     // 2. If the object application is not visible, it goes away when it's last
  479.     // object is released.   
  480.     //   
  481.     // CoLockObjectExternal can be used to increment the ref count of the application object
  482.     // when it is visible. This will implement shutdown behavior 1. When the application
  483.     // goes invisible, CoLockObjectExternal is used to decrement the ref count. This will
  484.     // implement shutdown behavior 2.
  485.     
  486.     if (m_bVisible)
  487.         CoLockObjectExternal(this, TRUE /*fLock*/, TRUE/*ignored when fLock==TRUE*/);
  488.     else CoLockObjectExternal(this, FALSE/*fLock*/, TRUE/*fLastLockReleases*/);  
  489.     ::ShowWindow (m_hwnd, nCmdShow);
  490. }
  491. STDMETHODIMP_(void)
  492. CApplication::CreateAndDrawLine()
  493. {   
  494.     LINEINFO lineinfo;
  495.     CLine FAR* pLine = NULL;
  496.     CPoint FAR* pPointStart = NULL;
  497.     CPoint FAR* pPointEnd = NULL; 
  498.     ILines FAR* pLines = NULL; 
  499.     int nRet;     
  500.     HRESULT hr;
  501.                   
  502.     nRet = DialogBoxParam(m_hinst, MAKEINTRESOURCE(IDD_DRAWLINE), m_hwnd, 
  503.                       (DLGPROC)DrawLineDialogFunc, (LPARAM)(LPLINEINFO)&lineinfo);    
  504.     if (nRet != IDOK) 
  505.         return;
  506.     hr = CLine::Create(&pLine);
  507.     if (FAILED(hr))  
  508.         goto error;
  509.     hr = CPoint::Create(&pPointStart);
  510.     if (FAILED(hr)) 
  511.         goto error; 
  512.     hr = CPoint::Create(&pPointEnd);
  513.     if (FAILED(hr))
  514.         goto error;
  515.     pPointStart->put_x(lineinfo.ptStart.x);
  516.     pPointStart->put_y(lineinfo.ptStart.y); 
  517.     pPointEnd->put_x(lineinfo.ptEnd.x);
  518.     pPointEnd->put_y(lineinfo.ptEnd.y);   
  519.     pLine->putref_StartPoint(pPointStart);  
  520.     pLine->putref_EndPoint(pPointEnd);  
  521.     pLine->put_Thickness(lineinfo.nThickness);
  522.     pLine->put_Color(lineinfo.colorref);
  523.     
  524.     hr = m_pPane->get_Lines(&pLines); 
  525.     if (FAILED(hr)) 
  526.         goto error; 
  527.     hr = pLines->Add(pLine); 
  528.     if (FAILED(hr)) 
  529.         goto error;  
  530.     pLines->Release();
  531.     return;
  532. error:
  533.     if (pLine) delete pLine;
  534.     if (pPointStart) delete pPointStart;
  535.     if (pPointEnd) delete pPointEnd; 
  536.     if (pLines) pLines->Release();   
  537.     MessageBox(m_hwnd, TEXT("Cannot create Line"), FROM_OLE_STRING(m_bstrName), MB_OK);
  538. }
  539. STDMETHODIMP_(void)
  540. CApplication::ClearPane()  
  541. {
  542.     m_pPane->Clear();
  543. }