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

Windows编程

开发平台:

Visual C++

  1. //=--------------------------------------------------------------------------=
  2. // CtlView.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1997 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of the IViewObjectEx interface, which is a moderately
  13. // non-trivial bunch of code.
  14. //
  15. #include "IPServer.H"
  16. #include "CtrlObj.H"
  17. #include "Globals.H"
  18. #include "Util.H"
  19. // for ASSERT and FAIL
  20. //
  21. SZTHISFILE
  22. // local functions we're going to find useful
  23. //
  24. HDC _CreateOleDC(DVTARGETDEVICE *ptd);
  25. //=--------------------------------------------------------------------------=
  26. // COleControl::Draw    [IViewObject2]
  27. //=--------------------------------------------------------------------------=
  28. // Draws a representation of an object onto the specified device context. 
  29. //
  30. // Parameters:
  31. //    DWORD                - [in] draw aspect
  32. //    LONG                 - [in] part of object to draw [not relevant]
  33. //    void *               - NULL
  34. //    DVTARGETDEVICE *     - [in] specifies the target device
  35. //    HDC                  - [in] information context for target device
  36. //    HDC                  - [in] target device context
  37. //    LPCRECTL             - [in] rectangle in which the object is drawn
  38. //    LPCRECTL             - [in] window extent and origin for metafiles
  39. //    BOOL (*)(DWORD)      - [in] callback for continuing or cancelling drawing
  40. //    DWORD                - [in] parameter to pass to callback.
  41. //
  42. // Output:
  43. //    HRESULT
  44. //
  45. // Notes:
  46. //    - we support the following OCX 96 extensions
  47. //        a. flicker free drawing [multi-pass drawing]
  48. //        b. pvAspect != NULL for optimized DC handling
  49. //        c. prcBounds == NULL for windowless inplace active objects
  50. //
  51. STDMETHODIMP COleControl::Draw
  52. (
  53.     DWORD            dwDrawAspect,
  54.     LONG             lIndex,
  55.     void            *pvAspect,
  56.     DVTARGETDEVICE  *ptd,
  57.     HDC              hicTargetDevice,
  58.     HDC              hdcDraw,
  59.     LPCRECTL         prcBounds,
  60.     LPCRECTL         prcWBounds,
  61.     BOOL (__stdcall *pfnContinue)(DWORD dwContinue),
  62.     DWORD            dwContinue
  63. )
  64. {
  65.     HRESULT hr;
  66.     RECTL rc;
  67.     POINT pVp, pW;
  68.     BOOL  fOptimize = FALSE;
  69.     int iMode;
  70.     BYTE fMetafile = FALSE;
  71.     BYTE fDeleteDC = FALSE;
  72.     // support the aspects required for multi-pass drawing
  73.     //
  74.     switch (dwDrawAspect) {
  75.         case DVASPECT_CONTENT:
  76.         case DVASPECT_OPAQUE:
  77.         case DVASPECT_TRANSPARENT:
  78.             break;
  79.         default:
  80.             return DV_E_DVASPECT;
  81.     }
  82.     // first, have to do a little bit to support printing.
  83.     //
  84.     if (GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE) {
  85.         // We are dealing with a metafile.
  86.         //
  87.         fMetafile = TRUE;
  88.         // If attributes DC is NULL, create one, based on ptd.
  89.         //
  90.         if (!hicTargetDevice) {
  91.             // Does _CreateOleDC have to return an hDC
  92.             // or can it be flagged to return an hIC 
  93.             // for this particular case?
  94.             //
  95.             hicTargetDevice = _CreateOleDC(ptd);
  96.             fDeleteDC = TRUE;
  97.         }
  98.     }
  99.     // check to see if we have any flags passed in the pvAspect parameter.
  100.     //
  101.     if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb == sizeof(DVASPECTINFO))
  102.         fOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE) ? TRUE : FALSE;
  103.     // if we are windowless, then we just pass this on to the end control code.
  104.     //
  105.     if (m_fInPlaceActive) {
  106.         // give them a rectangle with which to draw
  107.         //
  108.         //ASSERT(!m_fInPlaceActive || !prcBounds, "Inplace active and somebody passed in prcBounds!!!");
  109.         if (prcBounds)
  110. memcpy(&rc, prcBounds, sizeof(rc));
  111. else
  112. memcpy(&rc, &m_rcLocation, sizeof(rc));
  113.     } else {
  114.         // first -- convert the DC back to MM_TEXT mapping mode so that the
  115.         // window proc and OnDraw can share the same painting code.  save
  116.         // some information on it, so we can restore it later [without using
  117.         // a SaveDC/RestoreDC]
  118.         //
  119.         rc = *prcBounds;
  120.         // Don't do anything to hdcDraw if it's a metafile.
  121.         // The control's Draw method must make the appropriate
  122.         // accomodations for drawing to a metafile
  123.         //
  124.         if (!fMetafile) {
  125.             LPtoDP(hdcDraw, (POINT *)&rc, 2);
  126.             SetViewportOrgEx(hdcDraw, 0, 0, &pVp);
  127.             SetWindowOrgEx(hdcDraw, 0, 0, &pW);
  128.             iMode = SetMapMode(hdcDraw, MM_TEXT);
  129.         }
  130.     }
  131.     // prcWBounds is NULL and not used if we are not dealing with a metafile.
  132.     // For metafiles, we pass on rc as *prcBounds, we should also include
  133.     // prcWBounds
  134.     //
  135.     hr = OnDraw(dwDrawAspect, hdcDraw, &rc, prcWBounds, hicTargetDevice, fOptimize);
  136.     // clean up the DC when we're done with it, if appropriate.
  137.     //
  138.     if (!m_fInPlaceActive) {
  139.         SetViewportOrgEx(hdcDraw, pVp.x, pVp.y, NULL);
  140.         SetWindowOrgEx(hdcDraw, pW.x, pW.y, NULL);
  141.         SetMapMode(hdcDraw, iMode);
  142.     }
  143.     // if we created a dc, blow it away now
  144.     //
  145.     if (fDeleteDC) DeleteDC(hicTargetDevice);
  146.     return hr;
  147. }
  148. //=--------------------------------------------------------------------------=
  149. // COleControl::DoSuperClassPaint
  150. //=--------------------------------------------------------------------------=
  151. // design time painting of a subclassed control.
  152. //
  153. // Parameters:
  154. //    HDC                - [in]  dc to work with
  155. //    LPCRECTL           - [in]  rectangle to paint to.  should be in pixels
  156. //
  157. // Output:
  158. //    HRESULT
  159. //
  160. // Notes:
  161. //
  162. HRESULT COleControl::DoSuperClassPaint
  163. (
  164.     HDC      hdc,
  165.     LPCRECTL prcBounds
  166. )
  167. {
  168.     HWND hwnd;
  169.     RECT rcClient;
  170.     int  iMapMode;
  171.     POINT ptWOrg, ptVOrg;
  172.     SIZE  sWOrg, sVOrg;
  173.     // make sure we have a window.
  174.     //
  175.     hwnd = CreateInPlaceWindow(0,0, FALSE);
  176.     if (!hwnd)
  177.         return E_FAIL;
  178.     GetClientRect(hwnd, &rcClient);
  179.     // set up the DC for painting.  this code largely taken from the MFC CDK
  180.     // DoSuperClassPaint() fn.  doesn't always get things like command
  181.     // buttons quite right ...
  182.     //
  183.     // NOTE: there is a windows 95 problem in which the font instance manager
  184.     // will leak a bunch of bytes in the global GDI pool whenever you 
  185.     // change your extents and have an active font.  this code gets around
  186.     // this for on-screen cases, but not for printing [which shouldn't be
  187.     // too serious, because you're not often changing your control size and
  188.     // printing rapidly in succession]
  189.     //
  190.     if ((rcClient.right - rcClient.left != prcBounds->right - prcBounds->left)
  191.         && (rcClient.bottom - rcClient.top != prcBounds->bottom - prcBounds->top)) {
  192.         iMapMode = SetMapMode(hdc, MM_ANISOTROPIC);
  193.         SetWindowExtEx(hdc, rcClient.right, rcClient.bottom, &sWOrg);
  194.         SetViewportExtEx(hdc, prcBounds->right - prcBounds->left, prcBounds->bottom - prcBounds->top, &sVOrg);
  195.     }
  196.     SetWindowOrgEx(hdc, 0, 0, &ptWOrg);
  197.     SetViewportOrgEx(hdc, prcBounds->left, prcBounds->top, &ptVOrg);
  198. #if STRICT
  199.     CallWindowProc((WNDPROC)SUBCLASSWNDPROCOFCONTROL(m_ObjectType), hwnd, (g_fSysWin95Shell) ? WM_PRINT : WM_PAINT, (WPARAM)hdc, (LPARAM)(g_fSysWin95Shell ? PRF_CHILDREN | PRF_CLIENT : 0));
  200. #else
  201.     CallWindowProc((FARPROC)SUBCLASSWNDPROCOFCONTROL(m_ObjectType), hwnd, (g_fSysWin95Shell) ? WM_PRINT : WM_PAINT, (WPARAM)hdc, (LPARAM)(g_fSysWin95Shell ? PRF_CHILDREN | PRF_CLIENT : 0));
  202. #endif // STRICT
  203.     return S_OK;
  204. }
  205. //=--------------------------------------------------------------------------=
  206. // COleControl::GetColorSet    [IViewObject2]
  207. //=--------------------------------------------------------------------------=
  208. // Returns the logical palette that the control will use for drawing in its
  209. // IViewObject::Draw method with the corresponding parameters.
  210. //
  211. // Parameters:
  212. //    DWORD                - [in]  how the object is to be represented
  213. //    LONG                 - [in]  part of the object to draw [not relevant]
  214. //    void *               - NULL
  215. //    DVTARGETDEVICE *     - [in]  specifies the target device
  216. //    HDC                  - [in]  information context for the target device
  217. //    LOGPALETTE **        - [out] where to put palette
  218. //
  219. // Output:
  220. //    S_OK                 - Control has a palette, and returned it through the out param.
  221. //    S_FALSE              - Control does not currently have a palette.
  222. //    E_NOTIMPL            - Control will never have a palette so optimize handling of this control.
  223. //
  224. // Notes:
  225. //
  226. STDMETHODIMP COleControl::GetColorSet
  227. (
  228.     DWORD            dwDrawAspect,
  229.     LONG             lindex,
  230.     void            *IgnoreMe,
  231.     DVTARGETDEVICE  *ptd,
  232.     HDC              hicTargetDevice,
  233.     LOGPALETTE     **ppColorSet
  234. )
  235. {
  236.     if (dwDrawAspect != DVASPECT_CONTENT)
  237.         return DV_E_DVASPECT;
  238.     *ppColorSet = NULL;
  239.     return (OnGetPalette(hicTargetDevice, ppColorSet)) ? ((*ppColorSet) ? S_OK : S_FALSE) : E_NOTIMPL;
  240. }
  241. //=--------------------------------------------------------------------------=
  242. // COleControl::Freeze    [IViewObject2]
  243. //=--------------------------------------------------------------------------=
  244. // Freezes a certain aspect of the object's presentation so that it does not
  245. // change until the IViewObject::Unfreeze method is called.
  246. //
  247. // Parameters:
  248. //    DWORD            - [in] aspect
  249. //    LONG             - [in] part of object to draw
  250. //    void *           - NULL
  251. //    DWORD *          - [out] for Unfreeze
  252. //
  253. // Output:
  254. //    HRESULT
  255. //
  256. // Notes:
  257. //
  258. STDMETHODIMP COleControl::Freeze
  259. (
  260.     DWORD   dwDrawAspect,
  261.     LONG    lIndex,
  262.     void   *IgnoreMe,
  263.     DWORD  *pdwFreeze
  264. )
  265. {
  266.     return E_NOTIMPL;
  267. }
  268. //=--------------------------------------------------------------------------=
  269. // COleControl::Unfreeze    [IVewObject2]
  270. //=--------------------------------------------------------------------------=
  271. // Releases a previously frozen drawing. The most common use of this method
  272. // is for banded printing.
  273. //
  274. // Parameters:
  275. //    DWORD        - [in] cookie from freeze
  276. //
  277. // Output:
  278. //    HRESULT
  279. //
  280. // Notes:
  281. //
  282. STDMETHODIMP COleControl::Unfreeze
  283. (
  284.     DWORD dwFreeze
  285. )
  286. {
  287.     return E_NOTIMPL;
  288. }
  289. //=--------------------------------------------------------------------------=
  290. // COleControl::SetAdvise    [IViewObject2]
  291. //=--------------------------------------------------------------------------=
  292. // Sets up a connection between the control and an advise sink so that the
  293. // advise sink can be notified about changes in the control's view.
  294. //
  295. // Parameters:
  296. //    DWORD            - [in] aspect
  297. //    DWORD            - [in] info about the sink
  298. //    IAdviseSink *    - [in] the sink
  299. //
  300. // Output:
  301. //    HRESULT
  302. //
  303. // Notes:
  304. //
  305. STDMETHODIMP COleControl::SetAdvise
  306. (
  307.     DWORD        dwAspects,
  308.     DWORD        dwAdviseFlags,
  309.     IAdviseSink *pAdviseSink
  310. )
  311. {
  312.     // if it's not a content aspect, we don't support it.
  313.     //
  314.     if (!(dwAspects & DVASPECT_CONTENT)) {
  315.         return DV_E_DVASPECT;
  316.     }
  317.     // set up some flags  [we gotta stash for GetAdvise ...]
  318.     //
  319.     m_fViewAdvisePrimeFirst = (dwAdviseFlags & ADVF_PRIMEFIRST) ? TRUE : FALSE;
  320.     m_fViewAdviseOnlyOnce = (dwAdviseFlags & ADVF_ONLYONCE) ? TRUE : FALSE;
  321.     RELEASE_OBJECT(m_pViewAdviseSink);
  322.     m_pViewAdviseSink = pAdviseSink;
  323.     ADDREF_OBJECT(m_pViewAdviseSink);
  324.     // prime them if they want it [we need to store this so they can get flags later]
  325.     //
  326.     if (m_fViewAdvisePrimeFirst)
  327.         ViewChanged();
  328.     return S_OK;
  329. }
  330. //=--------------------------------------------------------------------------=
  331. // COleControl::GetAdvise    [IViewObject2]
  332. //=--------------------------------------------------------------------------=
  333. // Retrieves the existing advisory connection on the control if there is one.
  334. // This method simply returns the parameters used in the most recent call to
  335. // the IViewObject::SetAdvise method.
  336. //
  337. // Parameters:
  338. //    DWORD *            - [out]  aspects
  339. //    DWORD *            - [out]  advise flags
  340. //    IAdviseSink **     - [out]  the sink
  341. //
  342. // Output:
  343. //    HRESULT
  344. //
  345. // Notes;
  346. //
  347. STDMETHODIMP COleControl::GetAdvise
  348. (
  349.     DWORD        *pdwAspects,
  350.     DWORD        *pdwAdviseFlags,
  351.     IAdviseSink **ppAdviseSink
  352. )
  353. {
  354.     // if they want it, give it to them
  355.     //
  356.     if (pdwAspects)
  357.         *pdwAspects = DVASPECT_CONTENT;
  358.     if (pdwAdviseFlags) {
  359.         *pdwAdviseFlags = 0;
  360.         if (m_fViewAdviseOnlyOnce) *pdwAdviseFlags |= ADVF_ONLYONCE;
  361.         if (m_fViewAdvisePrimeFirst) *pdwAdviseFlags |= ADVF_PRIMEFIRST;
  362.     }
  363.     if (ppAdviseSink) {
  364.         *ppAdviseSink = m_pViewAdviseSink;
  365.         ADDREF_OBJECT(*ppAdviseSink);
  366.     }
  367.     return S_OK;
  368. }
  369. //=--------------------------------------------------------------------------=
  370. // COleControl::GetExtent    [IViewObject2]
  371. //=--------------------------------------------------------------------------=
  372. // Returns the size that the control will be drawn on the
  373. // specified target device.
  374. //
  375. // Parameters:
  376. //    DWORD            - [in] draw aspect
  377. //    LONG             - [in] part of object to draw
  378. //    DVTARGETDEVICE * - [in] information about target device
  379. //    LPSIZEL          - [out] where to put the size
  380. //
  381. // Output:
  382. //    HRESULT
  383. //
  384. // Notes:
  385. //
  386. STDMETHODIMP COleControl::GetExtent
  387. (
  388.     DWORD           dwDrawAspect,
  389.     LONG            lindex,
  390.     DVTARGETDEVICE *ptd,
  391.     LPSIZEL         psizel
  392. )
  393. {
  394.     // we already have an implementation of this [from IOleObject]
  395.     //
  396.     return GetExtent(dwDrawAspect, psizel);
  397. }
  398. //=--------------------------------------------------------------------------=
  399. // COleControl::OnGetPalette    [overridable]
  400. //=--------------------------------------------------------------------------=
  401. // called when the host wants palette information.  ideally, people should use
  402. // this sparingly and carefully.
  403. //
  404. // Parameters:
  405. //    HDC            - [in]  HIC for the target device
  406. //    LOGPALETTE **  - [out] where to put the palette
  407. //
  408. // Output:
  409. //    BOOL           - TRUE means we processed it, false means nope.
  410. //
  411. // Notes:
  412. //
  413. BOOL COleControl::OnGetPalette
  414. (
  415.     HDC          hicTargetDevice,
  416.     LOGPALETTE **ppColorSet
  417. )
  418. {
  419.     return FALSE;
  420. }
  421. //=--------------------------------------------------------------------------=
  422. // COleControl::GetRect    [IViewObjectEx]
  423. //=--------------------------------------------------------------------------=
  424. // returns a rectnagle describing a given drawing aspect
  425. //
  426. // Parameters:
  427. //    DWORD             - [in]  aspect
  428. //    LPRECTL           - [out] region rectangle
  429. //
  430. // Output:
  431. //    HRESULT
  432. //
  433. // Notes:
  434. //
  435. STDMETHODIMP COleControl::GetRect
  436. (
  437.     DWORD    dvAspect,
  438.     LPRECTL  prcRect
  439. )
  440. {
  441.     RECTL rc;
  442.     BOOL  f;
  443.     // call the user routine and let them return the size
  444.     //
  445.     f = OnGetRect(dvAspect, &rc);
  446.     if (!f) return DV_E_DVASPECT;
  447.     // transform these dudes.
  448.     //
  449.     PixelToHiMetric((LPSIZEL)&rc, (LPSIZEL)prcRect);
  450.     PixelToHiMetric((LPSIZEL)(LPBYTE)&rc + sizeof(SIZEL), (LPSIZEL)((LPBYTE)prcRect + sizeof(SIZEL)));
  451.     return S_OK;
  452. }
  453. //=--------------------------------------------------------------------------=
  454. // COleControl::GetViewStatus    [IViewObjectEx]
  455. //=--------------------------------------------------------------------------=
  456. // returns information about the opactiy of the object and what drawing
  457. // aspects are supported
  458. //
  459. // Parameters:
  460. //    DWORD *            - [out] the status
  461. //
  462. /// Output:
  463. //    HRESULT
  464. //
  465. // Notes:
  466. //
  467. STDMETHODIMP COleControl::GetViewStatus
  468. (
  469.     DWORD *pdwStatus
  470. )
  471. {
  472.     // depending on the flag in the CONTROLOBJECTINFO structure, indicate our
  473.     // transparency vs opacity.
  474.     // OVERRIDE:  controls that wish to support multi-pass drawing should
  475.     // override this routine and return, in addition to the flags indication
  476.     // opacity, flags indicating what sort of drawing aspects they support.
  477.     //
  478.     *pdwStatus = FCONTROLISOPAQUE(m_ObjectType) ? VIEWSTATUS_OPAQUE : 0;
  479.     return S_OK;
  480. }
  481. //=--------------------------------------------------------------------------=
  482. // COleControl::QueryHitPoint    [IViewObjectEx]
  483. //=--------------------------------------------------------------------------=
  484. // indicates whether a point is within a given aspect of an object.
  485. //
  486. // Parameters:
  487. //    DWORD                - [in]  aspect
  488. //    LPCRECT              - [in]  Bounds rectangle
  489. //    POINT                - [in]  hit location client coordinates
  490. //    LONG                 - [in]  what the container considers close
  491. //    DWORD *              - [out] info about the hit
  492. //
  493. // Output:
  494. //    HRESULT
  495. //
  496. // Notes:
  497. //
  498. STDMETHODIMP COleControl::QueryHitPoint
  499. (
  500.     DWORD    dvAspect,
  501.     LPCRECT  prcBounds,
  502.     POINT    ptLocation,
  503.     LONG     lCloseHint,
  504.     DWORD   *pdwHitResult
  505. )
  506. {
  507.     // OVERRIDE: override me if you want to provide additional [non-opaque]
  508.     // functionality
  509.     //
  510.     if (dvAspect != DVASPECT_CONTENT)
  511.         return DV_E_DVASPECT;
  512.     *pdwHitResult = PtInRect(prcBounds, ptLocation) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  513.     return S_OK;
  514. }
  515. //=--------------------------------------------------------------------------=
  516. // COleControl::QueryHitRect    [IViewObjectEx]
  517. //=--------------------------------------------------------------------------=
  518. // indicates wheter any point in a rectangle is within a given drawing aspect
  519. // of an object.
  520. //
  521. // Parameters:
  522. //    DWORD            - [in]  aspect
  523. //    LPCRECT          - [in]  bounds
  524. //    LPCRECT          - [in]  location
  525. //    LONG             - [in]  what host considers close
  526. //    DWORD *          - [out] hit result
  527. //
  528. // Output:
  529. //    HRESULT
  530. //
  531. // Notes:
  532. //
  533. STDMETHODIMP COleControl::QueryHitRect
  534. (
  535.     DWORD     dvAspect,
  536.     LPCRECT   prcBounds,
  537.     LPCRECT   prcLocation,
  538.     LONG      lCloseHint,
  539.     DWORD    *pdwHitResult
  540. )
  541. {
  542.     RECT rc;
  543.     // OVERRIDE: override this for additional behaviour
  544.     //
  545.     if (dvAspect != DVASPECT_CONTENT)
  546.         return DV_E_DVASPECT;
  547.     *pdwHitResult = IntersectRect(&rc, prcBounds, prcLocation) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
  548.     return S_OK;
  549. }
  550. //=--------------------------------------------------------------------------=
  551. // COleControl::GetNaturalExtent    [IViewObjectEx]
  552. //=--------------------------------------------------------------------------=
  553. // supports two types of control sizing, content and integral.
  554. //
  555. // Parameters:
  556. //    DWORD            - [in]  aspect
  557. //    LONG             - [in]  index
  558. //    DVTARGETDEVICE * - [in]  target device information
  559. //    HDC              - [in]  HIC
  560. //    DVEXTENTINFO *   - [in]  sizing data
  561. //    LPSIZEL          - [out] sizing data retunred by control
  562. //
  563. // Output:
  564. //    HRESULT
  565. //
  566. // Notes:
  567. //
  568. STDMETHODIMP COleControl::GetNaturalExtent
  569. (
  570.     DWORD           dvAspect,
  571.     LONG            lIndex,
  572.     DVTARGETDEVICE *ptd,
  573.     HDC             hicTargetDevice,
  574.     DVEXTENTINFO   *pExtentInfo,
  575.     LPSIZEL         pSizel
  576. )
  577. {
  578.     return E_NOTIMPL;
  579. }
  580. //=--------------------------------------------------------------------------=
  581. // COleControl::OnGetRect    [overridable
  582. //=--------------------------------------------------------------------------=
  583. // returns our rectangle
  584. //
  585. // Parameters:
  586. //    DWORD              - [in]  aspect they want the rect for
  587. //    RECTL *            - [out] the rectangle that matches this aspect
  588. //
  589. // Output:
  590. //    BOOL               - false means we don't like the aspect
  591. //
  592. // Notes:
  593. //
  594. BOOL COleControl::OnGetRect
  595. (
  596.     DWORD   dvAspect,
  597.     RECTL  *pRect
  598. )
  599. {
  600.     // by default, we only support content drawing.
  601.     //
  602.     if (dvAspect != DVASPECT_CONTENT)
  603.         return FALSE;
  604.     // just give them our bounding rectangle
  605.     //
  606.     *((LPRECT)pRect) = m_rcLocation;
  607.     return TRUE;
  608. }
  609. //=--------------------------------------------------------------------------=
  610. // _CreateOleDC
  611. //=--------------------------------------------------------------------------=
  612. // creates an HDC given a DVTARGETDEVICE structure.
  613. //
  614. // Parameters:
  615. //    DVTARGETDEVICE *              - [in] duh.
  616. //
  617. // Output:
  618. //    HDC
  619. //
  620. // Notes:
  621. //
  622. HDC _CreateOleDC
  623. (
  624.     DVTARGETDEVICE *ptd
  625. )
  626. {
  627.     LPDEVMODEW   pDevModeW;
  628.     DEVMODEA     DevModeA, *pDevModeA;
  629.     LPOLESTR     lpwszDriverName;
  630.     LPOLESTR     lpwszDeviceName;
  631.     LPOLESTR     lpwszPortName;
  632.     HDC          hdc;
  633.     // return screen DC for NULL target device
  634.     //
  635.     if (!ptd)
  636.         return CreateDC("DISPLAY", NULL, NULL, NULL);
  637.     if (ptd->tdExtDevmodeOffset == 0)
  638.         pDevModeW = NULL;
  639.     else
  640.         pDevModeW = (LPDEVMODEW)((LPSTR)ptd + ptd->tdExtDevmodeOffset);
  641.     lpwszDriverName = (LPOLESTR)((BYTE*)ptd + ptd->tdDriverNameOffset);
  642.     lpwszDeviceName = (LPOLESTR)((BYTE*)ptd + ptd->tdDeviceNameOffset);
  643.     lpwszPortName   = (LPOLESTR)((BYTE*)ptd + ptd->tdPortNameOffset);
  644.     MAKE_ANSIPTR_FROMWIDE(pszDriverName, lpwszDriverName);
  645.     MAKE_ANSIPTR_FROMWIDE(pszDeviceName, lpwszDeviceName);
  646.     MAKE_ANSIPTR_FROMWIDE(pszPortName,   lpwszPortName);
  647.     // wow, this sucks.
  648.     //
  649.     if (pDevModeW) {
  650.         WideCharToMultiByte(CP_ACP, 0, pDevModeW->dmDeviceName, -1, (LPSTR)DevModeA.dmDeviceName, CCHDEVICENAME, NULL, NULL);
  651. memcpy(&DevModeA.dmSpecVersion, &pDevModeW->dmSpecVersion,
  652. offsetof(DEVMODEA, dmFormName) - offsetof(DEVMODEA, dmSpecVersion));
  653.         WideCharToMultiByte(CP_ACP, 0, pDevModeW->dmFormName, -1, (LPSTR)DevModeA.dmFormName, CCHFORMNAME, NULL, NULL);
  654. memcpy(&DevModeA.dmLogPixels, &pDevModeW->dmLogPixels, sizeof(DEVMODEA) - offsetof(DEVMODEA, dmLogPixels));
  655.         if (pDevModeW->dmDriverExtra) {
  656.             pDevModeA = (DEVMODEA *)HeapAlloc(g_hHeap, 0, sizeof(DEVMODEA) + pDevModeW->dmDriverExtra);
  657.             if (!pDevModeA) return NULL;
  658.             memcpy(pDevModeA, &DevModeA, sizeof(DEVMODEA));
  659.             memcpy(pDevModeA + 1, pDevModeW + 1, pDevModeW->dmDriverExtra);
  660.         } else
  661.             pDevModeA = &DevModeA;
  662. DevModeA.dmSize = sizeof(DEVMODEA);
  663.     } else
  664.         pDevModeA = NULL;
  665.     hdc = CreateDC(pszDriverName, pszDeviceName, pszPortName, pDevModeA);
  666.     if (pDevModeA != &DevModeA) HeapFree(g_hHeap, 0, pDevModeA);
  667.     return hdc;
  668. }