home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap10 / ddataobj / dataobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  7.7 KB  |  332 lines

  1. /*
  2.  * DATAOBJ.CPP
  3.  * Data Object Chapter 10
  4.  *
  5.  * Implementation of CDataObject and CImpIDataObject that work
  6.  * in either an EXE or DLL.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "dataobj.h"
  17.  
  18. extern HINSTANCE   g_hInst;
  19.  
  20. DWORD              g_dwID=0;
  21.  
  22. //Names of data sizes
  23. static TCHAR * rgszSize[3]={TEXT("Small"), TEXT("Medium")
  24.     , TEXT("Large")};
  25.  
  26.  
  27.  
  28. /*
  29.  * CDataObject::CDataObject
  30.  * CDataObject::~CDataObject
  31.  *
  32.  * Parameters (Constructor):
  33.  *  pUnkOuter       LPUNKNOWN of controlling unknown, if it exists.
  34.  *  pfnDestroy      PFNDESTROYED to call when object is destroyed.
  35.  *  iSize           UINT specifying the size of the data set to use.
  36.  */
  37.  
  38. CDataObject::CDataObject(LPUNKNOWN pUnkOuter
  39.     , PFNDESTROYED pfnDestroy, UINT iSize)
  40.     {
  41.     UINT        i;
  42.  
  43.     m_cRef=0;
  44.     m_pUnkOuter=pUnkOuter;
  45.     m_pfnDestroy=pfnDestroy;
  46.     m_iSize=iSize;
  47.  
  48.     m_hWndAdvise=NULL;
  49.     m_dwAdvFlags=ADVF_NODATA;
  50.  
  51.     //NULL any contained interfaces initially.
  52.     m_pImpIDataObject=NULL;
  53.     m_pIDataAdviseHolder=NULL;
  54.  
  55.     //Initilize the FORMATETCs arrays we use for EnumFormatEtc
  56.     m_cfeGet=CFORMATETCGET;
  57.  
  58.     SETDefFormatEtc(m_rgfeGet[0], CF_METAFILEPICT, TYMED_MFPICT);
  59.     SETDefFormatEtc(m_rgfeGet[1], CF_BITMAP, TYMED_GDI);
  60.     SETDefFormatEtc(m_rgfeGet[2], CF_TEXT, TYMED_HGLOBAL);
  61.  
  62.     for (i=0; i < DOSIZE_CSIZES; i++)
  63.         m_rghBmp[i]=NULL;
  64.  
  65.     return;
  66.     }
  67.  
  68.  
  69. CDataObject::~CDataObject(void)
  70.     {
  71.     UINT        i;
  72.  
  73.     for (i=0; i < DOSIZE_CSIZES; i++)
  74.         {
  75.         if (NULL!=m_rghBmp[i])
  76.             DeleteObject(m_rghBmp[i]);
  77.         }
  78.  
  79.     ReleaseInterface(m_pIDataAdviseHolder);
  80.     DeleteInterfaceImp(m_pImpIDataObject);
  81.  
  82.     if (NULL!=m_hWndAdvise)
  83.         DestroyWindow(m_hWndAdvise);
  84.  
  85.     return;
  86.     }
  87.  
  88.  
  89.  
  90. /*
  91.  * CDataObject::Init
  92.  *
  93.  * Purpose:
  94.  *  Performs any intiailization of a CDataObject that's prone to
  95.  *  failure that we also use internally before exposing the
  96.  *  object outside.
  97.  *
  98.  * Parameters:
  99.  *  None
  100.  *
  101.  * Return Value:
  102.  *  BOOL            TRUE if the function is successful,
  103.  *                  FALSE otherwise.
  104.  */
  105.  
  106. BOOL CDataObject::Init(void)
  107.     {
  108.     LPUNKNOWN       pIUnknown=this;
  109.     UINT            i;
  110.     TCHAR           szTemp[80];
  111.     UINT            cy;
  112.  
  113.     if (NULL!=m_pUnkOuter)
  114.         pIUnknown=m_pUnkOuter;
  115.  
  116.     //Allocate contained interfaces.
  117.     m_pImpIDataObject=new CImpIDataObject(this, pIUnknown);
  118.  
  119.     if (NULL==m_pImpIDataObject)
  120.         return FALSE;
  121.  
  122.     for (i=0; i < DOSIZE_CSIZES; i++)
  123.         {
  124.         m_rghBmp[i]=LoadBitmap(g_hInst, MAKEINTRESOURCE(i+IDB_MIN));
  125.  
  126.         if (NULL==m_rghBmp[i])
  127.             return FALSE;
  128.         }
  129.  
  130.  
  131.     /*
  132.      * Register the Advise window class first time through
  133.      * (g_dwID==0)
  134.      */
  135.  
  136.     if (0L==g_dwID)
  137.         {
  138.         WNDCLASS    wc;
  139.  
  140.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  141.         wc.lpfnWndProc    = AdvisorWndProc;
  142.         wc.cbClsExtra     = 0;
  143.         wc.cbWndExtra     = sizeof(PCDataObject);
  144.         wc.hInstance      = g_hInst;
  145.         wc.hIcon          = LoadIcon(g_hInst
  146.             , MAKEINTRESOURCE(IDR_ADVISORICON));
  147.         wc.hCursor        = NULL;
  148.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  149.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  150.         wc.lpszClassName  = TEXT("Advisor");
  151.  
  152.         if (!RegisterClass(&wc))
  153.             return FALSE;
  154.         }
  155.  
  156.     /*
  157.      * Create an advise window with a unique caption:
  158.      * "<size> <module> Advisor #xx" where <size> is Small,
  159.      * Medium, or Large, <module> is EXE or DLL, and xx is
  160.      * counted globally every time a CDataObject is created.
  161.      */
  162.  
  163.     g_dwID++;
  164.    #ifdef EXEDATAOBJECT
  165.     wsprintf(szTemp, TEXT("%s EXE Advisor #%lu")
  166.         , (LPTSTR)rgszSize[m_iSize], g_dwID);
  167.    #else
  168.     wsprintf(szTemp, TEXT("%s DLL Advisor #%lu")
  169.         , (LPTSTR)rgszSize[m_iSize], g_dwID);
  170.    #endif
  171.  
  172.     cy=(GetSystemMetrics(SM_CYBORDER)*2)+GetSystemMetrics(SM_CYMENU)
  173.         + GetSystemMetrics(SM_CYCAPTION);
  174.  
  175.     m_hWndAdvise=CreateWindow(TEXT("Advisor"), szTemp
  176.         , WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_BORDER
  177.         | WS_VISIBLE, 400, 35+(g_dwID*(cy+30)), 200, cy
  178.         , HWND_DESKTOP, NULL, g_hInst, this);
  179.  
  180.     if (NULL==m_hWndAdvise)
  181.         return FALSE;
  182.  
  183.     return TRUE;
  184.     }
  185.  
  186.  
  187.  
  188.  
  189.  
  190. /*
  191.  * CDataObject::QueryInterface
  192.  * CDataObject::AddRef
  193.  * CDataObject::Release
  194.  *
  195.  * Purpose:
  196.  *  IUnknown members for CDataObject object.
  197.  */
  198.  
  199. STDMETHODIMP CDataObject::QueryInterface(REFIID riid, PPVOID ppv)
  200.     {
  201.     *ppv=NULL;
  202.  
  203.     if (IID_IUnknown==riid)
  204.         *ppv=this;
  205.  
  206.     if (IID_IDataObject==riid)
  207.         *ppv=m_pImpIDataObject;
  208.  
  209.     if (NULL!=*ppv)
  210.         {
  211.         ((LPUNKNOWN)*ppv)->AddRef();
  212.         return NOERROR;
  213.         }
  214.  
  215.     return ResultFromScode(E_NOINTERFACE);
  216.     }
  217.  
  218.  
  219. STDMETHODIMP_(ULONG) CDataObject::AddRef(void)
  220.     {
  221.     return ++m_cRef;
  222.     }
  223.  
  224.  
  225. STDMETHODIMP_(ULONG) CDataObject::Release(void)
  226.     {
  227.     if (0!=--m_cRef)
  228.         return m_cRef;
  229.  
  230.     if (NULL!=m_pfnDestroy)
  231.         (*m_pfnDestroy)();
  232.  
  233.     delete this;
  234.     return 0;
  235.     }
  236.  
  237.  
  238.  
  239.  
  240.  
  241. /*
  242.  * AdvisorWndProc
  243.  *
  244.  * Purpose:
  245.  *  Standard window class procedure.
  246.  */
  247.  
  248. LRESULT APIENTRY AdvisorWndProc(HWND hWnd, UINT iMsg
  249.     , WPARAM wParam, LPARAM lParam)
  250.     {
  251.     PCDataObject    pDO;
  252.     DWORD           i;
  253.     DWORD           iAdvise;
  254.     DWORD           dwTime;
  255.     DWORD           dwAvg;
  256.     TCHAR           szTime[128];
  257.     TCHAR           szTitle[80];
  258.     HCURSOR         hCur, hCurT;
  259.  
  260.     pDO=(PCDataObject)GetWindowLong(hWnd, 0);
  261.  
  262.     switch (iMsg)
  263.         {
  264.         case WM_NCCREATE:
  265.             pDO=(PCDataObject)(((LPCREATESTRUCT)lParam)
  266.                 ->lpCreateParams);
  267.             SetWindowLong(hWnd, 0, (LONG)pDO);
  268.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  269.  
  270.         case WM_CLOSE:
  271.             //Forbid task manager from closing us.
  272.             return 0L;
  273.  
  274.         case WM_COMMAND:
  275.             if (NULL==pDO->m_pIDataAdviseHolder)
  276.                 break;
  277.  
  278.             //Send IAdviseSink::OnDataChange many times.
  279.             i=(DWORD)(LOWORD(wParam)-IDM_ADVISEITERATIONSMIN+1);
  280.             iAdvise=(i*i)*16;
  281.  
  282.             hCur=LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
  283.             hCurT=SetCursor(hCur);
  284.             ShowCursor(TRUE);
  285.  
  286.             dwTime=GetTickCount();
  287.  
  288.             i=0;
  289.             while (TRUE)
  290.                 {
  291.                #ifdef EXEDATAOBJECT
  292.                #ifndef WIN32
  293.                 MSG     msg;
  294.  
  295.                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  296.                     {
  297.                     TranslateMessage(&msg);
  298.                     DispatchMessage(&msg);
  299.                     }
  300.                 else
  301.                #endif
  302.                #endif
  303.                     {
  304.                     pDO->m_pIDataAdviseHolder->SendOnDataChange
  305.                         (pDO->m_pImpIDataObject, 0, ADVF_NODATA);
  306.  
  307.                     if (++i >= iAdvise)
  308.                         break;
  309.                     }
  310.                 }
  311.  
  312.             dwTime=GetTickCount()-dwTime;
  313.             dwAvg=dwTime/iAdvise;
  314.  
  315.             SetCursor(hCurT);
  316.             ShowCursor(FALSE);
  317.  
  318.             wsprintf(szTime
  319.                 , TEXT("Total=%lu ms\n\rAverage=%lu ms")
  320.                 , dwTime, dwAvg);
  321.  
  322.             GetWindowText(hWnd, szTitle, sizeof(szTitle));
  323.             MessageBox(hWnd, szTime, szTitle, MB_OK);
  324.             break;
  325.  
  326.         default:
  327.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  328.         }
  329.  
  330.     return 0L;
  331.     }
  332.