home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / atlbutton / atlbutton.h < prev    next >
C/C++ Source or Header  |  1998-03-26  |  8KB  |  336 lines

  1. // AtlButton.h : Declaration of the CAtlButton
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include "resource.h"       // main symbols
  14. #include "dibapi.h"
  15. #include "cpatlbutn.h"
  16.  
  17. //////////////////////////////////////////////////////////////////////////////////////////////////
  18. // CTimer
  19. template <class Derived, class T, const IID* piid>
  20. class CTimer
  21. {
  22. public:
  23.  
  24.     CTimer()
  25.     {
  26.         m_bTimerOn = FALSE;
  27.     }
  28.  
  29.     HRESULT TimerOn(DWORD dwTimerInterval)
  30.     {
  31.         Derived* pDerived = ((Derived*)this);
  32.  
  33.         m_dwTimerInterval = dwTimerInterval;
  34.         if (m_bTimerOn) // already on, just change interval
  35.             return S_OK;
  36.  
  37.         m_bTimerOn = TRUE;
  38.         m_dwTimerInterval = dwTimerInterval;
  39.         m_pStream = NULL;
  40.  
  41.         HRESULT hRes;
  42.  
  43.         hRes = CoMarshalInterThreadInterfaceInStream(*piid, (T*)pDerived, &m_pStream);
  44.  
  45.         // Create thread and pass the thread proc the this ptr
  46.         m_hThread = CreateThread(NULL, 0, &_Apartment, (void*)this, 0, &m_dwThreadID);
  47.  
  48.         return S_OK;
  49.     }
  50.  
  51.     void TimerOff()
  52.     {
  53.         if (m_bTimerOn)
  54.         {
  55.             m_bTimerOn = FALSE;
  56.             AtlWaitWithMessageLoop(m_hThread);
  57.         }
  58.     }
  59.  
  60.  
  61. // Implementation
  62. private:
  63.     static DWORD WINAPI _Apartment(void* pv)
  64.     {
  65.         CTimer<Derived, T, piid>* pThis = (CTimer<Derived, T, piid>*) pv;
  66.         pThis->Apartment();
  67.         return 0;
  68.     }
  69.  
  70.     DWORD Apartment()
  71.     {
  72.         CoInitialize(NULL);
  73.         HRESULT hRes;
  74.  
  75.         m_spT.Release();
  76.  
  77.         if (m_pStream)
  78.             hRes = CoGetInterfaceAndReleaseStream(m_pStream, *piid, (void**)&m_spT);
  79.  
  80.         while(m_bTimerOn)
  81.         {
  82.             Sleep(m_dwTimerInterval);
  83.             if (!m_bTimerOn)
  84.                 break;
  85.  
  86.             m_spT->_OnTimer();
  87.         }
  88.         m_spT.Release();
  89.  
  90.         CoUninitialize();
  91.         return 0;
  92.     }
  93.  
  94. // Attributes
  95. public:
  96.     DWORD m_dwTimerInterval;
  97.  
  98. // Implementation
  99. private:
  100.     HANDLE m_hThread;
  101.     DWORD m_dwThreadID;
  102.     LPSTREAM m_pStream;
  103.     CComPtr<T> m_spT;
  104.     BOOL m_bTimerOn;
  105. };
  106.  
  107.  
  108. /////////////////////////////////////////////////////////////////////////////
  109. // CAtlButton
  110. class CAtlButton :
  111.     public CComObjectRoot,
  112.     public CTimer<CAtlButton, IAtlButton, &IID_IAtlButton>,
  113.     public CComCoClass<CAtlButton,&CLSID_CAtlButton>,
  114.     public CComControl<CAtlButton>,
  115.     public IDispatchImpl<IAtlButton, &IID_IAtlButton, &LIBID_ATLBUTNLib>,
  116.     public IPersistStreamInitImpl<CAtlButton>,
  117.     public IOleControlImpl<CAtlButton>,
  118.     public IOleObjectImpl<CAtlButton>,
  119.     public IOleInPlaceActiveObjectImpl<CAtlButton>,
  120.     public IViewObjectExImpl<CAtlButton>,
  121.     public IOleInPlaceObjectWindowlessImpl<CAtlButton>,
  122.     public IProvideClassInfo2Impl<&CLSID_CAtlButton, &DIID__ATLButton, &LIBID_ATLBUTNLib>,
  123.     public IPersistPropertyBagImpl<CAtlButton>,
  124.     public IConnectionPointContainerImpl<CAtlButton>,
  125.     public CProxy_ATLButton<CAtlButton>,
  126.     public IObjectSafetyImpl<CAtlButton, INTERFACESAFE_FOR_UNTRUSTED_CALLER>
  127. {
  128. public:
  129.     CAtlButton()
  130.     {
  131.         m_nEntry = 0;
  132.         m_hDIB[0] = NULL;
  133.         m_hDIB[1] = NULL;
  134.         m_hDIB[2] = NULL;
  135.         m_hPal[0] = NULL;
  136.         m_hPal[1] = NULL;
  137.         m_hPal[2] = NULL;
  138.     }
  139.  
  140. DECLARE_REGISTRY_RESOURCEID(IDR_AtlButton)
  141.  
  142.  
  143. BEGIN_COM_MAP(CAtlButton)
  144.     COM_INTERFACE_ENTRY(IDispatch)
  145.     COM_INTERFACE_ENTRY(IAtlButton)
  146.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  147.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  148.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  149.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  150.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  151.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  152.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  153.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  154.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  155.     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  156.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  157.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  158.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IPersist, IPersistPropertyBag)
  159.     COM_INTERFACE_ENTRY_IMPL(IPersistPropertyBag)
  160.     COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  161.     COM_INTERFACE_ENTRY(IObjectSafety)
  162. END_COM_MAP()
  163.  
  164. BEGIN_PROPERTY_MAP(CAtlButton)
  165.     PROP_ENTRY("Static_Image", 0, CLSID_NULL)
  166.     PROP_ENTRY("Hover_Image", 1, CLSID_NULL)
  167.     PROP_ENTRY("Push_Image", 2, CLSID_NULL)
  168. END_PROPERTY_MAP()
  169.  
  170. BEGIN_CONNECTION_POINT_MAP(CAtlButton)
  171.     CONNECTION_POINT_ENTRY(DIID__ATLButton)
  172. END_CONNECTION_POINT_MAP()
  173.  
  174. BEGIN_MSG_MAP(CAtlButton)
  175.     MESSAGE_HANDLER(WM_ERASEBKGND, OnErase)
  176.     MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
  177.     MESSAGE_HANDLER(WM_LBUTTONDOWN, OnButtonDown)
  178.     MESSAGE_HANDLER(WM_LBUTTONUP, OnButtonUp)
  179.     MESSAGE_HANDLER(WM_PAINT, OnPaint)
  180. END_MSG_MAP()
  181.  
  182.     LRESULT OnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  183.     {
  184.         return 0;
  185.     }
  186.     LRESULT OnButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  187.     {
  188.         m_nEntry = 2;
  189.         FireViewChange();
  190.         OnClick();
  191.         return 0;
  192.     }
  193.     LRESULT OnButtonUp(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  194.     {
  195.         m_nEntry = 1;
  196.         FireViewChange();
  197.         OnClick();
  198.         return 0;
  199.     }
  200.     LRESULT OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  201.     {
  202.         if (m_nEntry == 0)
  203.         {
  204.             m_nEntry = 1;
  205.             FireViewChange();
  206.         }
  207.         return 0;
  208.     }
  209.  
  210. // IAtlButton
  211. public:
  212.     CComBSTR m_bstrFilename[3];
  213.     RECT m_rcDIB[3];
  214.     HDIB m_hDIB[3];
  215.     HPALETTE m_hPal[3];
  216.     int m_nEntry;
  217.  
  218.     void PutImage(BSTR strFilename, int nEntry)
  219.     {
  220.         USES_CONVERSION;
  221.         m_bstrFilename[nEntry] = strFilename;
  222.         if (m_hDIB[nEntry])
  223.             GlobalFree(m_hDIB[nEntry]);
  224.         if (m_hPal[nEntry])
  225.             GlobalFree(m_hPal[nEntry]);
  226.         m_hDIB[nEntry] = NULL;
  227.         m_hPal[nEntry] = NULL;
  228.         m_hDIB[nEntry] = ReadDIBFile(OLE2T(strFilename));
  229.         if (m_hDIB[nEntry])
  230.         {
  231.             CreateDIBPalette(m_hDIB[nEntry], &m_hPal[nEntry]);
  232.             LPSTR pDIB = (LPSTR)GlobalLock(m_hDIB[nEntry]);
  233.             m_rcDIB[nEntry].left = 0;
  234.             m_rcDIB[nEntry].top = 0;
  235.             m_rcDIB[nEntry].right = DIBWidth(pDIB);
  236.             m_rcDIB[nEntry].bottom = DIBHeight(pDIB);
  237.             GlobalUnlock((HGLOBAL)m_hDIB[nEntry]);
  238.         }
  239.     }
  240.     STDMETHOD(put_ImageStatic)(BSTR strFilename)
  241.     {
  242.         PutImage(strFilename, 0);
  243.         return S_OK;
  244.     }
  245.     STDMETHOD(get_ImageStatic)(BSTR* pstrFilename)
  246.     {
  247.         *pstrFilename = m_bstrFilename[0].Copy();
  248.         return S_OK;
  249.     }
  250.     STDMETHOD(put_ImageHover)(BSTR strFilename)
  251.     {
  252.         PutImage(strFilename, 1);
  253.         return S_OK;
  254.     }
  255.     STDMETHOD(get_ImageHover)(BSTR* pstrFilename)
  256.     {
  257.         *pstrFilename = m_bstrFilename[1].Copy();
  258.         return S_OK;
  259.     }
  260.     STDMETHOD(put_ImagePush)(BSTR strFilename)
  261.     {
  262.         PutImage(strFilename, 2);
  263.         return S_OK;
  264.     }
  265.     STDMETHOD(get_ImagePush)(BSTR* pstrFilename)
  266.     {
  267.         *pstrFilename = m_bstrFilename[2].Copy();
  268.         return S_OK;
  269.     }
  270.     STDMETHOD(_OnTimer)()
  271.     {
  272.         POINT pos;
  273.         GetCursorPos(&pos);
  274.         if (m_bInPlaceActive)
  275.         {
  276.             HWND hwnd;
  277.             m_spInPlaceSite->GetWindow(&hwnd);
  278.             ::ScreenToClient(hwnd, &pos);
  279.  
  280.             if (!PtInRect(&m_rcPos, pos))
  281.             {
  282.                 if (m_nEntry > 0)
  283.                 {
  284.                     m_nEntry = 0;
  285.                     FireViewChange();
  286.                 }
  287.             }
  288.         }
  289.  
  290.         return S_OK;
  291.     }
  292.     HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect = NULL)
  293.     {
  294.         HRESULT hr;
  295.  
  296.         hr = CComControl<CAtlButton>::InPlaceActivate(iVerb, prcPosRect);
  297.         TimerOn(250);
  298.         return hr;
  299.     }
  300.     STDMETHOD(InPlaceDeactivate)(void)
  301.     {
  302.         TimerOff();
  303.         return IOleInPlaceObjectWindowlessImpl<CAtlButton>::InPlaceDeactivate();
  304.     }
  305.  
  306.     HRESULT OnDraw(ATL_DRAWINFO& di)
  307.     {
  308.         USES_CONVERSION;
  309.  
  310.         if (m_hDIB[m_nEntry])
  311.         {
  312.             HPALETTE hPal = SelectPalette(di.hdcDraw, m_hPal[m_nEntry], TRUE);
  313.             RealizePalette(di.hdcDraw);
  314.             PaintDIB(di.hdcDraw, (LPRECT) di.prcBounds, m_hDIB[m_nEntry], &m_rcDIB[m_nEntry], m_hPal[m_nEntry]);
  315.             SelectPalette(di.hdcDraw, hPal, TRUE);
  316.         }
  317.         return 0;
  318.     }
  319.  
  320.     STDMETHOD(QueryHitPoint)(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
  321.     {
  322.         if (dwAspect == DVASPECT_CONTENT)
  323.         {
  324.             *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  325.             if (m_nEntry == 0)
  326.             {
  327.                 m_nEntry = 1;
  328.                 FireViewChange();
  329.             }
  330.             return S_OK;
  331.         }
  332.         ATLTRACE(_T("Wrong DVASPECT\n"));
  333.         return E_FAIL;
  334.     }
  335. };
  336.