home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / BOCOLE.PAK / BOLEPICT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  12.7 KB  |  470 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectComponents
  3. // Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
  4. //
  5. // $Revision:   2.4  $
  6. //
  7. //  Implements the Bolero versoin of the OLE2 picture object.
  8. //----------------------------------------------------------------------------
  9. #include "BOle.h"
  10. #include "BOleCMan.h"
  11. #include "BOlePict.h"
  12. #include "BOcxCtrl.h"
  13. #include "BConnPnt.h"
  14. #include <OleCtl.h>
  15.  
  16.  
  17. //-----------
  18. //  BOlePict implementation
  19. //
  20.  
  21. // rayk - need to ensure that this object supports IPersistStream
  22. BOlePicture::BOlePicture (BOleClassManager *pF, IBUnknownMain * pO) :
  23.         BOleComponent (pF, pO),
  24.         Width (0),                     Height (0),
  25.         pTI (NULLP),                   pTL (NULLP),
  26.         KeepOriginalFormat (FALSE),    hdc (0),
  27.         Attrib (0),                    pEventList (NULLP)
  28. {
  29.   HRESULT err = LoadTypeLib (OLESTR ("bole.tlb"), &pTL);
  30.   if (!err) {
  31.     ITypeInfo *pTI;
  32.     err = pTL->GetTypeInfoOfGuid (IID_BOlePicture, &pTI);
  33.   }
  34.   memset (&Pict, 0, sizeof (PICTDESC));
  35.   Pict.cbSizeofstruct = sizeof (PICTDESC);
  36.  
  37.   // EventHandler deal with ConnecctionPoints
  38.   pEventList = new BEventList (1);
  39.   if (pEventList) {
  40.     pEventList->AddRef();
  41.     pEventList->AddEventsSet (IID_IPropertyNotifySink, AsPIUnknown(this), 5);
  42.   }
  43. }
  44.  
  45.  
  46. BOlePicture::~BOlePicture ()
  47. {
  48.   if (pTI)
  49.     pTI->Release ();
  50.   if (pTL)
  51.     pTL->Release ();
  52.   if (pEventList)
  53.     pEventList->Release();
  54. }
  55.  
  56.  
  57. HRESULT _IFUNC BOlePicture::QueryInterfaceMain (REFIID iid, LPVOID FAR *ppv)
  58. {
  59.    HRESULT hr = ResultFromScode(E_NOINTERFACE);
  60.    *ppv = NULL;
  61.  
  62.    // Self
  63.    //
  64.    if (iid == IID_BOlePicture) {
  65.       (BOlePicture *)*ppv = this;
  66.       AddRef();
  67.       return NOERROR;
  68.    }
  69.  
  70.    // interfaces
  71.    if (SUCCEEDED(hr = IPicture_QueryInterface (this, iid, ppv))) {
  72.    }
  73.    else if (SUCCEEDED(hr = IPictureDisp_QueryInterface (this, iid, ppv))) {
  74.    }
  75.    else if (SUCCEEDED(hr = IConnectionPointContainer_QueryInterface(this, iid, ppv))) {
  76.    }
  77.    else if (SUCCEEDED(hr = IDispatch_QueryInterface(this, iid, ppv))) {
  78.    }
  79.    else if (SUCCEEDED(hr = IBPicture_QueryInterface(this, iid, ppv))) {
  80.    }
  81.    else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))) {
  82.    }
  83.    return hr;
  84. }
  85.  
  86. HRESULT _IFUNC BOlePicture::SetPictureDesc (LPVOID pPD)
  87. {
  88.   PICTDESC *pPicDes = (PICTDESC *)pPD;
  89.  
  90.   if (pPicDes->cbSizeofstruct == sizeof (PICTDESC)) {
  91.     Width = 0;   Height = 0;   hdc = 0;
  92.     memcpy (&Pict, pPD, sizeof (PICTDESC));
  93.     if (Pict.picType == PICTYPE_BITMAP) {
  94.       BITMAP bmp;
  95.       GetObject (Pict.bmp.hbitmap, sizeof (BITMAP), &bmp);
  96.       Width = bmp.bmWidth;
  97.       Height = bmp.bmHeight;
  98.     }
  99.     return NOERROR;
  100.   }
  101.   return ResultFromScode (E_INVALIDARG);
  102. }
  103.  
  104. HRESULT _IFUNC BOlePicture::GetHandle (HANDLE FAR* phandle) 
  105. {
  106.   *phandle = (HANDLE) Pict.bmp.hbitmap;
  107.   return NOERROR;
  108. }
  109.  
  110. HRESULT _IFUNC BOlePicture::Draw (HDC hdc, long x, long y, long cx, long cy,
  111.                      long xSrc, long ySrc, long cxSrc, long cySrc,
  112.                      LPCRECT lprcWBounds)
  113. {
  114.   return Render (hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc,
  115.                     lprcWBounds);
  116. }
  117.  
  118. HRESULT _IFUNC BOlePicture::PictChanged ()
  119. {
  120.   return PictureChanged ();
  121. }
  122.  
  123. HRESULT _IFUNC BOlePicture::Render (HDC hdcOut, 
  124.                 long x, long y, long cx, long cy,
  125.                     OLE_XPOS_HIMETRIC xSrc, OLE_YPOS_HIMETRIC ySrc,
  126.                     OLE_XSIZE_HIMETRIC cxSrc, OLE_YSIZE_HIMETRIC cySrc,
  127.                     LPCRECT lprcWBounds)
  128. {
  129.   HRESULT   hr = NOERROR;
  130.   // rayk - if Attrib == PICTURE_TRANSPARENT???
  131.   // rayk - Do we need to check GetDeviceCaps for not support of StretchBlt?
  132.   // rayk - hpal - SelectPalette last param should be true or false? (i.e. bForceBackground
  133.  
  134.   if ((!Pict.bmp.hbitmap) || (cx == 0) || (cy == 0))
  135.     return hr;
  136.  
  137.   if (Pict.picType == PICTYPE_BITMAP) {
  138.  
  139.     HPALETTE  hOldPal = 0;
  140.     HBITMAP   hOldBmp = 0;
  141.     if (!hdc) {    
  142.       HDC   hScreenDC = GetDC (NULL);
  143.       hdc = CreateCompatibleDC (hScreenDC);
  144.       ReleaseDC (NULL, hScreenDC);
  145.       hOldBmp = (HBITMAP) SelectObject (hdc, Pict.bmp.hbitmap);
  146.     } 
  147.  
  148.     if (Pict.bmp.hpal) {
  149.       hOldPal = SelectPalette (hdcOut, Pict.bmp.hpal, FALSE);
  150.       RealizePalette (hdcOut);
  151.     }
  152.     if (Attrib & PICTURE_SCALABLE) {
  153.       StretchBlt (hdcOut, x, y, cx, cy, hdc, xSrc, ySrc, cxSrc, cySrc,
  154.                              SRCCOPY);
  155.     } else {
  156.       BitBlt (hdcOut, x, y, cx, cy, hdc, xSrc, ySrc, SRCCOPY);
  157.     }
  158.     if (hOldBmp) {
  159.       SelectObject (hdc, hOldBmp);
  160.       ReleaseDC (NULL, hdc);
  161.       hdc = 0;
  162.     }
  163.     if (Pict.bmp.hpal) {
  164.       SelectPalette (hdcOut, hOldPal, TRUE);
  165.       RealizePalette (hdcOut);
  166.     }
  167.  
  168.   } else if (Pict.picType == PICTYPE_ICON) {
  169.  
  170.     DrawIcon (hdcOut, x, y, Pict.icon.hicon);
  171.  
  172.   } else if (Pict.picType == PICTYPE_METAFILE) {
  173.  
  174.     int   SavedDC;
  175.     POINT ViewOrg;
  176.  
  177.     SavedDC = SaveDC (hdcOut);
  178.     //  Set mapping mode to MM_ANISOTROPIC since we want the coordinate space 
  179.     //  to allow a non-1 by 1 mapping. Note the order of these calls is 
  180.     //  essential.  The mapping mode must be set to MM_ANISOTROPIC or 
  181.     //  Windows will ignore the WindowExt change which must preceed a 
  182.     //  ViewportExt change. 
  183.     SetMapMode (hdcOut, MM_ANISOTROPIC);
  184.     //  Set the logical size of the DC to be the maximum X and maximum Y 
  185.     //  used in the metafile's drawing 
  186.     SetWindowExtEx (hdcOut, Pict.wmf.xExt, Pict.wmf.yExt, NULL);
  187.     //  Set the DC 'window' (logical coordinate extent) to map on to the 
  188.     //  entire rectangle provided.  
  189.     SetViewportExtEx (hdcOut, cx, cy, NULL);
  190.     //  Get the original viewport origin since we are relative to that 
  191.     GetViewportOrgEx (hdcOut, &ViewOrg);
  192.     //  Move the viewport origin to match the top left of the rectangle 
  193.     SetViewportOrgEx (hdcOut, ViewOrg.x + x, ViewOrg.y + y, NULL);
  194.     //  Now that the metafile's coordinate space has been setup, play the
  195.     //  metafile 
  196.     PlayMetaFile (hdcOut, Pict.wmf.hmeta);
  197.     //  Reset everything back the way it came. 
  198.     RestoreDC (hdcOut, SavedDC);
  199.   }
  200.   return hr;
  201. }
  202.  
  203. HRESULT _IFUNC BOlePicture::get_Handle (OLE_HANDLE FAR* phandle)
  204. {
  205.   *phandle = (OLE_HANDLE)Pict.bmp.hbitmap;
  206.   return NOERROR;
  207. }
  208.  
  209. HRESULT _IFUNC BOlePicture::get_hPal (OLE_HANDLE FAR* phpal)
  210. {
  211.   *phpal = 0;
  212.   if (Pict.picType == PICTYPE_BITMAP)
  213.     *phpal = (OLE_HANDLE)Pict.bmp.hpal;
  214.   return NOERROR;
  215. }
  216.  
  217. HRESULT _IFUNC BOlePicture::get_Type (short FAR* ptype)
  218. {
  219.   *ptype = Pict.picType;
  220.   return NOERROR;
  221. }
  222.  
  223. HRESULT _IFUNC BOlePicture::get_Width (OLE_XSIZE_HIMETRIC FAR* pwidth)
  224. {
  225.   *pwidth = Width;
  226.   return NOERROR;
  227. }
  228.  
  229. HRESULT _IFUNC BOlePicture::get_Height (OLE_YSIZE_HIMETRIC FAR* pheight)
  230. {
  231.   *pheight = Height;
  232.   return NOERROR;
  233. }
  234.  
  235. HRESULT _IFUNC BOlePicture::get_KeepOriginalFormat (BOOL * pfkeep)
  236. {
  237.   *pfkeep = KeepOriginalFormat;
  238.   return NOERROR;
  239. }
  240.  
  241. HRESULT _IFUNC BOlePicture::get_Attributes (DWORD FAR * lpdwAttr)
  242. {
  243.   *lpdwAttr = Attrib;  // rayk - where does this get set?
  244.   return NOERROR;
  245. }
  246.  
  247. HRESULT _IFUNC BOlePicture::put_KeepOriginalFormat (BOOL fkeep)
  248. {
  249.   // rayk - still need to implement KeepOriginalFormat
  250.   // e.g. if bitmap is loaded in 24bit format, keep it around, or convert to 8-bit?
  251.   KeepOriginalFormat = fkeep;
  252.   return NOERROR;
  253. }
  254.  
  255. HRESULT _IFUNC BOlePicture::set_hPal (OLE_HANDLE hpal)
  256. {
  257.   if (Pict.picType == PICTYPE_BITMAP) {
  258.     if (PropRequestEdit (DISPID_PICT_HPAL) == S_OK) {
  259.       (OLE_HANDLE)Pict.bmp.hpal = hpal;
  260.       PropChanged (DISPID_PICT_HPAL);
  261.     }
  262.   }
  263.   return NOERROR;
  264. }
  265.  
  266. HRESULT _IFUNC BOlePicture::SelectPicture (HDC hdcIn, HDC FAR * phdcOut, 
  267.                 OLE_HANDLE FAR * phbmpOut)
  268. {
  269.   if (phdcOut)
  270.     *phdcOut = 0;
  271.   if (phbmpOut)
  272.     *phbmpOut = 0;
  273.   if ((Pict.picType == PICTYPE_BITMAP) && Pict.bmp.hbitmap) {
  274.     HBITMAP hBmpOld;
  275.     if (phdcOut)
  276.       *phdcOut = hdc;
  277.  
  278.     hBmpOld = (HBITMAP) SelectObject (hdcIn, Pict.bmp.hbitmap);
  279.     hdc = hdcIn;
  280.     if (phbmpOut)
  281.       *phbmpOut = (OLE_HANDLE)hBmpOld;
  282.     return NOERROR;
  283.   }
  284.   return ResultFromScode (E_NOTIMPL);
  285. }
  286.  
  287. HRESULT _IFUNC BOlePicture::get_CurDC (HDC FAR * phdcOut)
  288. {
  289.   *phdcOut = hdc;
  290.   return NOERROR;
  291. }
  292.  
  293. HRESULT _IFUNC BOlePicture::PictureChanged ()
  294. {
  295.   PropChanged (DISPID_PICT_HANDLE);
  296.   return NOERROR;
  297. }
  298.  
  299. HRESULT _IFUNC BOlePicture::SaveAsFile (LPSTREAM lpstream, BOOL fSaveMemCopy,
  300.                     LONG FAR * lpcbSize)
  301. {
  302.   return ResultFromScode (E_NOTIMPL);
  303. }
  304.  
  305. HRESULT _IFUNC BOlePicture::GetTypeInfoCount (UINT FAR* pctinfo)         
  306. {
  307.   *pctinfo = 1;
  308.   if (!pTI)
  309.     *pctinfo = 0;
  310.   return NOERROR;
  311. }
  312.  
  313.  
  314. HRESULT _IFUNC BOlePicture::GetTypeInfo (UINT itinfo, LCID lcid,          
  315.    ITypeInfo FAR* FAR* pptinfo)                               
  316. {
  317.   if (!pTI)
  318.     return ResultFromScode (E_NOTIMPL);
  319.   *pptinfo = pTI;
  320.   return NOERROR;
  321. }
  322.  
  323.  
  324. HRESULT _IFUNC BOlePicture::GetIDsOfNames (REFIID riid, LPOLESTR FAR* rgszNames,
  325.    UINT cNames, LCID lcid, DISPID FAR* rgdispid)              
  326. {
  327.   return DispGetIDsOfNames (pTI, rgszNames, cNames, rgdispid);
  328. }
  329.  
  330.  
  331. HRESULT _IFUNC BOlePicture::Invoke (DISPID dispidMember, REFIID riid, LCID lcid,
  332.    WORD wFlags, DISPPARAMS FAR* pargs, VARIANT FAR* pVarResult,
  333.    EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr)             
  334. {
  335.   HRESULT    hr = NOERROR;
  336.  
  337.   if (pVarResult)
  338.      VariantInit (pVarResult);
  339.  
  340.   if ( !(wFlags & DISPATCH_PROPERTYGET|DISPATCH_PROPERTYPUT))
  341.     return ResultFromScode(E_INVALIDARG);
  342.  
  343.   if (wFlags & DISPATCH_PROPERTYGET) {
  344.  
  345.     if ( !((IID_NULL == riid) && (pVarResult)))
  346.       return ResultFromScode(E_INVALIDARG);
  347.  
  348.     switch (dispidMember)
  349.     {
  350.       case DISPID_PICT_HEIGHT:
  351.          V_I4 (pVarResult) = Height;
  352.          V_VT (pVarResult) = VT_I4;
  353.          break;
  354.  
  355.       case DISPID_PICT_WIDTH:
  356.          V_I4 (pVarResult) = Width;
  357.          V_VT (pVarResult) = VT_I4;
  358.          break;
  359.  
  360.       case DISPID_PICT_TYPE:
  361.          V_I2 (pVarResult) = Pict.picType;
  362.          V_VT (pVarResult) = VT_I2;
  363.          break;
  364.  
  365.       case DISPID_PICT_HANDLE:
  366.          V_I4 (pVarResult) = (OLE_HANDLE)Pict.bmp.hbitmap;
  367.          V_VT (pVarResult) = VT_I4;
  368.          break;
  369.  
  370.       case DISPID_PICT_HPAL:
  371.          V_I4 (pVarResult) = 0;
  372.          if (Pict.picType == PICTYPE_BITMAP)
  373.            V_I4 (pVarResult) = (OLE_HANDLE)Pict.bmp.hpal;
  374.          V_VT (pVarResult) = VT_I4;
  375.          break;
  376.  
  377.     }
  378.   } else if (wFlags & DISPATCH_PROPERTYPUT) {
  379.  
  380.      if ((pargs->cArgs != 1) || (pargs->cNamedArgs != 1))
  381.        return ResultFromScode(E_INVALIDARG);
  382.      if (pargs->rgdispidNamedArgs[0] != DISPID_PROPERTYPUT)
  383.        return ResultFromScode(E_INVALIDARG);
  384.  
  385.     switch (dispidMember)
  386.     {
  387.       case DISPID_PICT_HPAL: 
  388.          hr = set_hPal (V_I4 (pargs->rgvarg));  
  389.          break;
  390.     }
  391.   }
  392.   return hr;
  393. }
  394.  
  395. // IConnectionPointContainer methods 
  396. //
  397. HRESULT _IFUNC BOlePicture::EnumConnectionPoints 
  398.                                 (LPENUMCONNECTIONPOINTS FAR* ppEnum)
  399. {
  400.   // if at least one connection point is here, return the collection!
  401.   HRESULT hr = ResultFromScode (E_NOINTERFACE);
  402.   if (pEventList && (*pEventList)[0]) {
  403.     hr = pEventList->QueryInterface (IID_IEnumConnectionPoints, 
  404.                                                    (LPVOID *)ppEnum);
  405.   }
  406.   return hr;
  407. }
  408.  
  409. HRESULT _IFUNC BOlePicture::FindConnectionPoint (REFIID iid, LPCONNECTIONPOINT FAR* ppCP)
  410. {
  411.   // only one connection point for BOlePicture (i.e. IPropertyNotifySink)
  412.   //
  413.   HRESULT hr = ResultFromScode (E_NOINTERFACE);
  414.   IID     TempIID;
  415.  
  416.   (*pEventList)[0]->GetConnectionInterface (&TempIID); // get iid
  417.   if (TempIID == iid) {
  418.     IConnectionPoint *pCP = (*pEventList)[0];
  419.     pCP->AddRef ();
  420.     *ppCP = pCP;
  421.     hr = NOERROR;
  422.   }
  423.   return hr;
  424. }
  425.  
  426. // Service prop notify sink connection point
  427. //
  428. HRESULT BOlePicture::PropChanged (DISPID dispid)
  429. {
  430.   IBSinkList    *pSinkList;
  431.   IBEventClass  *pEC;
  432.   IPropertyNotifySink *pSink;
  433.  
  434.  
  435.   (*pEventList)[0]->QueryInterface (IID_IBEventClass, &(LPVOID) pEC);
  436.   pEC->GetSinkList (&pSinkList);
  437.   pSinkList->Reset();
  438.   while (pSinkList->NextSink (&(LPVOID)pSink) == S_OK){
  439.     pSink->OnChanged (dispid);
  440.     pSink->Release ();
  441.   }
  442.   pEC->Release ();
  443.   return NOERROR;
  444. }
  445.  
  446.  
  447. HRESULT BOlePicture::PropRequestEdit (DISPID dispid)
  448. {
  449.   HRESULT result = NOERROR;
  450.   IBSinkList    *pSinkList;
  451.   IBEventClass  *pEC;
  452.   IPropertyNotifySink *pSink;
  453.  
  454.   (*pEventList)[0]->QueryInterface (IID_IBEventClass, &(LPVOID) pEC);
  455.   pEC->GetSinkList (&pSinkList);
  456.   pSinkList->Reset ();
  457.   while (pSinkList->NextSink (&(LPVOID)pSink) == S_OK){
  458.     result = pSink->OnRequestEdit (dispid);
  459.     pSink->Release ();
  460.     if (FAILED (result)) 
  461.       break;
  462.   }
  463.   pEC->Release ();
  464.   return result;
  465. }
  466.  
  467.  
  468.  
  469.  
  470.