home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / shell / regview / dockwndw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-27  |  14.8 KB  |  626 lines

  1. /**************************************************************************
  2.    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3.    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4.    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5.    PARTICULAR PURPOSE.
  6.  
  7.    Copyright 1997 Microsoft Corporation.  All Rights Reserved.
  8. **************************************************************************/
  9.  
  10. /**************************************************************************
  11.  
  12.    File:          DockWndw.cpp
  13.    
  14.    Description:   Implements CDockingWindow
  15.  
  16. **************************************************************************/
  17.  
  18. /**************************************************************************
  19.    #include statements
  20. **************************************************************************/
  21.  
  22. #include "DockWndw.h"
  23.  
  24. #if (_WIN32_IE >= 0x0400)
  25.  
  26. /**************************************************************************
  27.  
  28.    CDockingWindow::CDockingWindow()
  29.  
  30. **************************************************************************/
  31.  
  32. CDockingWindow::CDockingWindow(CShellView *pView, HWND hwndCommand)
  33. {
  34. m_pView = pView;
  35. if(m_pView)
  36.    {
  37.    m_pView->AddRef();
  38.    }
  39. else
  40.    {
  41.    delete this;
  42.    return;
  43.    }
  44.  
  45. m_pSite = NULL;
  46.  
  47. m_hWnd = NULL;
  48.  
  49. m_hwndCommand = hwndCommand;
  50.  
  51. m_bFocus = FALSE;
  52.  
  53. m_rcDisplay.left = 0;
  54. m_rcDisplay.top = 0;
  55. m_rcDisplay.right = 0;
  56. m_rcDisplay.bottom = 0;
  57.  
  58. m_ObjRefCount = 1;
  59. g_DllRefCount++;
  60. }
  61.  
  62. /**************************************************************************
  63.  
  64.    CDockingWindow::~CDockingWindow()
  65.  
  66. **************************************************************************/
  67.  
  68. CDockingWindow::~CDockingWindow()
  69. {
  70. if(m_pView)
  71.    {
  72.    m_pView->Release();
  73.    }
  74.  
  75. g_DllRefCount--;
  76. }
  77.  
  78. ///////////////////////////////////////////////////////////////////////////
  79. //
  80. // IUnknown Implementation
  81. //
  82.  
  83. /**************************************************************************
  84.  
  85.    CDockingWindow::QueryInterface
  86.  
  87. **************************************************************************/
  88.  
  89. STDMETHODIMP CDockingWindow::QueryInterface(REFIID riid, LPVOID *ppReturn)
  90. {
  91. *ppReturn = NULL;
  92.  
  93. //IUnknown
  94. if(IsEqualIID(riid, IID_IUnknown))
  95.    {
  96.    *ppReturn = this;
  97.    }
  98.  
  99. //IOleWindow
  100. else if(IsEqualIID(riid, IID_IOleWindow))
  101.    {
  102.    *ppReturn = (IOleWindow*)this;
  103.    }
  104.  
  105. //IDockingWindow
  106. else if(IsEqualIID(riid, IID_IDockingWindow))
  107.    {
  108.    *ppReturn = (IDockingWindow*)this;
  109.    }   
  110.  
  111. //IInputObject
  112. else if(IsEqualIID(riid, IID_IInputObject))
  113.    {
  114.    *ppReturn = (IInputObject*)this;
  115.    }   
  116.  
  117. //IObjectWithSite
  118. else if(IsEqualIID(riid, IID_IObjectWithSite))
  119.    {
  120.    *ppReturn = (IObjectWithSite*)this;
  121.    }   
  122.  
  123. if(*ppReturn)
  124.    {
  125.    (*(LPUNKNOWN*)ppReturn)->AddRef();
  126.    return S_OK;
  127.    }
  128.  
  129. return E_NOINTERFACE;
  130. }                                             
  131.  
  132. /**************************************************************************
  133.  
  134.    CDockingWindow::AddRef
  135.  
  136. **************************************************************************/
  137.  
  138. STDMETHODIMP_(DWORD) CDockingWindow::AddRef()
  139. {
  140. return ++m_ObjRefCount;
  141. }
  142.  
  143.  
  144. /**************************************************************************
  145.  
  146.    CDockingWindow::Release
  147.  
  148. **************************************************************************/
  149.  
  150. STDMETHODIMP_(DWORD) CDockingWindow::Release()
  151. {
  152. if(--m_ObjRefCount == 0)
  153.    {
  154.    delete this;
  155.    return 0;
  156.    }
  157.    
  158. return m_ObjRefCount;
  159. }
  160.  
  161. ///////////////////////////////////////////////////////////////////////////
  162. //
  163. // IOleWindow Implementation
  164. //
  165.  
  166. /**************************************************************************
  167.  
  168.    CDockingWindow::GetWindow()
  169.    
  170. **************************************************************************/
  171.  
  172. STDMETHODIMP CDockingWindow::GetWindow(HWND *phWnd)
  173. {
  174. *phWnd = m_hWnd;
  175.  
  176. return S_OK;
  177. }
  178.  
  179. /**************************************************************************
  180.  
  181.    CDockingWindow::ContextSensitiveHelp()
  182.    
  183. **************************************************************************/
  184.  
  185. STDMETHODIMP CDockingWindow::ContextSensitiveHelp(BOOL fEnterMode)
  186. {
  187. return E_NOTIMPL;
  188. }
  189.  
  190. ///////////////////////////////////////////////////////////////////////////
  191. //
  192. // IDockingWindow Implementation
  193. //
  194.  
  195. /**************************************************************************
  196.  
  197.    CDockingWindow::ShowDW()
  198.    
  199. **************************************************************************/
  200.  
  201. STDMETHODIMP CDockingWindow::ShowDW(BOOL fShow)
  202. {
  203. //if our window doesn't exist yet, create it now
  204. if(!m_hWnd && m_pSite)
  205.    {
  206.    HRESULT  hr;
  207.  
  208.    //if our window class has not been registered, then do so
  209.    WNDCLASS wc;
  210.    if(!GetClassInfo(g_hInst, SHTB_CLASS_NAME, &wc))
  211.       {
  212.       ZeroMemory(&wc, sizeof(wc));
  213.       wc.style          = CS_HREDRAW | CS_VREDRAW;
  214.       wc.lpfnWndProc    = (WNDPROC)WndProc;
  215.       wc.cbClsExtra     = 0;
  216.       wc.cbWndExtra     = 0;
  217.       wc.hInstance      = g_hInst;
  218.       wc.hIcon          = NULL;
  219.       wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  220.       wc.hbrBackground  = (HBRUSH)CreateSolidBrush(RGB(192, 0, 0));
  221.       wc.lpszMenuName   = NULL;
  222.       wc.lpszClassName  = SHTB_CLASS_NAME;
  223.       
  224.       if(!RegisterClass(&wc))
  225.          {
  226.          //if this fails, CreateWindow will fail, so don't sweat it
  227.          }
  228.       }
  229.  
  230.    //get our parent window
  231.    hr = m_pSite->GetWindow(&m_hwndParent);
  232.    if(SUCCEEDED(hr))
  233.       {
  234.       RECT  rc;
  235.  
  236.       GetClientRect(m_hwndParent, &rc);
  237.  
  238.       //create the window - use zero for pos and size - it will get positioned and sized below
  239.       CreateWindowEx(   WS_EX_CLIENTEDGE,
  240.                         SHTB_CLASS_NAME,
  241.                         NULL,
  242.                         WS_CHILD | WS_CLIPSIBLINGS,
  243.                         0,
  244.                         0,
  245.                         0,
  246.                         0,
  247.                         m_hwndParent,
  248.                         NULL,
  249.                         g_hInst,
  250.                         (LPVOID)this);
  251.       
  252.       if(!m_hWnd)
  253.          return E_FAIL;
  254.       
  255.       NegotiateBorderSpace(m_pSite);
  256.       }
  257.    }
  258.  
  259. if(m_hWnd && m_pSite)
  260.    {
  261.    BORDERWIDTHS   bwRequest = {0, 0, 0, 0};
  262.  
  263.    if(fShow)
  264.       {
  265.       //position the window - m_rcDisplay was set up in NegotiateBorderSpace
  266.       MoveWindow( m_hWnd,
  267.                   m_rcDisplay.left,
  268.                   m_rcDisplay.top,
  269.                   m_rcDisplay.right,
  270.                   m_rcDisplay.bottom,
  271.                   TRUE);
  272.    
  273.       //show our window
  274.       ShowWindow(m_hWnd, SW_SHOW);
  275.       }
  276.    else
  277.       {
  278.       //hide our window
  279.       ShowWindow(m_hWnd, SW_HIDE);
  280.  
  281.       //release our border space - bwRequest was initialized above
  282.       m_pSite->SetBorderSpaceDW((IDockingWindow*)this, &bwRequest);
  283.       }
  284.    }
  285.  
  286. return S_OK;
  287. }
  288.  
  289. /**************************************************************************
  290.  
  291.    CDockingWindow::CloseDW()
  292.    
  293. **************************************************************************/
  294.  
  295. STDMETHODIMP CDockingWindow::CloseDW(DWORD dwReserved)
  296. {
  297. if(m_pSite)
  298.    {
  299.    ShowDW(FALSE);
  300.  
  301.    if(IsWindow(m_hWnd))
  302.       DestroyWindow(m_hWnd);
  303.    
  304.    m_pSite->Release();
  305.    m_pSite = NULL;
  306.    }
  307.  
  308. return S_OK;
  309. }
  310.  
  311. /**************************************************************************
  312.  
  313.    CDockingWindow::ResizeBorderDW()
  314.    
  315. **************************************************************************/
  316.  
  317. STDMETHODIMP CDockingWindow::ResizeBorderDW(LPCRECT prcBorder, IUnknown* punkSite, BOOL fReserved)
  318. {
  319. IDockingWindowSite   *pSite = NULL;
  320.  
  321. //if punkSite is not NULL, use it to negotiate our border space
  322. if(punkSite)
  323.    {
  324.    if(FAILED(punkSite->QueryInterface(IID_IDockingWindowSite, (LPVOID*)&pSite)))
  325.       {
  326.       return E_FAIL;
  327.       }
  328.    }
  329. else if(m_pSite)
  330.    {
  331.    pSite = m_pSite;
  332.    pSite->AddRef();
  333.    }
  334.  
  335. if(pSite)
  336.    {
  337.    HRESULT  hr = E_FAIL;
  338.  
  339.    if(NegotiateBorderSpace(pSite, prcBorder))
  340.       {
  341.       //updated our window's position
  342.       ShowDW(TRUE);
  343.       hr = S_OK;
  344.       }
  345.    
  346.    pSite->Release();
  347.    return hr;
  348.    }
  349. return E_FAIL;
  350. }
  351.  
  352. ///////////////////////////////////////////////////////////////////////////
  353. //
  354. // IInputObject Implementation
  355. //
  356.  
  357. /**************************************************************************
  358.  
  359.    CDockingWindow::UIActivateIO()
  360.    
  361. **************************************************************************/
  362.  
  363. STDMETHODIMP CDockingWindow::UIActivateIO(BOOL fActivate, LPMSG pMsg)
  364. {
  365. if(fActivate)
  366.    SetFocus(m_hWnd);
  367.  
  368. return S_OK;
  369. }
  370.  
  371. /**************************************************************************
  372.  
  373.    CDockingWindow::HasFocusIO()
  374.    
  375.    If this window or one of its decendants has the focus, return S_OK. Return 
  376.    S_FALSE if we don't have the focus.
  377.  
  378. **************************************************************************/
  379.  
  380. STDMETHODIMP CDockingWindow::HasFocusIO(void)
  381. {
  382. if(m_bFocus)
  383.    return S_OK;
  384.  
  385. return S_FALSE;
  386. }
  387.  
  388. /**************************************************************************
  389.  
  390.    CDockingWindow::TranslateAcceleratorIO()
  391.    
  392.    If the accelerator is translated, return S_OK or S_FALSE otherwise.
  393.  
  394. **************************************************************************/
  395.  
  396. STDMETHODIMP CDockingWindow::TranslateAcceleratorIO(LPMSG pMsg)
  397. {
  398. return S_FALSE;
  399. }
  400.  
  401. ///////////////////////////////////////////////////////////////////////////
  402. //
  403. // IObjectWithSite implementations
  404. //
  405.  
  406. /**************************************************************************
  407.  
  408.    CDockingWindow::SetSite()
  409.    
  410. **************************************************************************/
  411.  
  412. STDMETHODIMP CDockingWindow::SetSite(IUnknown* punkSite)
  413. {
  414. if(m_pSite)
  415.    {
  416.    m_pSite->Release();
  417.    m_pSite = NULL;
  418.    }
  419.  
  420. //If punkSite is not NULL, we are connecting to the site.
  421. if(punkSite)
  422.    {
  423.    if(SUCCEEDED(punkSite->QueryInterface(IID_IDockingWindowSite, (LPVOID*)&m_pSite)))
  424.       {
  425.       return S_OK;
  426.       }
  427.    }
  428.  
  429. return S_OK;
  430. }
  431.  
  432. /**************************************************************************
  433.  
  434.    CDockingWindow::GetSite()
  435.    
  436. **************************************************************************/
  437.  
  438. STDMETHODIMP CDockingWindow::GetSite(REFIID riid, LPVOID *ppvReturn)
  439. {
  440. *ppvReturn = NULL;
  441.  
  442. if(m_pSite)
  443.    return m_pSite->QueryInterface(riid, ppvReturn);
  444.  
  445. return E_FAIL;
  446. }
  447.  
  448. ///////////////////////////////////////////////////////////////////////////
  449. //
  450. // private method implementations
  451. //
  452.  
  453. /**************************************************************************
  454.  
  455.    CDockingWindow::WndProc()
  456.    
  457. **************************************************************************/
  458.  
  459. LRESULT CALLBACK CDockingWindow::WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  460. {
  461. CDockingWindow  *pThis = (CDockingWindow*)GetWindowLong(hWnd, GWL_USERDATA);
  462.  
  463. switch (uMessage)
  464.    {
  465.    case WM_NCCREATE:
  466.       {
  467.       LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
  468.       pThis = (CDockingWindow*)(lpcs->lpCreateParams);
  469.       SetWindowLong(hWnd, GWL_USERDATA, (LONG)pThis);
  470.  
  471.       //set the window handle
  472.       pThis->m_hWnd = hWnd;
  473.       }
  474.       break;
  475.    
  476.    case WM_PAINT:
  477.       return pThis->OnPaint();
  478.    
  479.    case WM_COMMAND:
  480.       return pThis->OnCommand(wParam, lParam);
  481.    
  482.    case WM_SETFOCUS:
  483.       return pThis->OnSetFocus();
  484.  
  485.    case WM_KILLFOCUS:
  486.       return pThis->OnKillFocus();
  487.    }
  488.  
  489. return DefWindowProc(hWnd, uMessage, wParam, lParam);
  490. }
  491.  
  492. /**************************************************************************
  493.  
  494.    CDockingWindow::OnPaint()
  495.    
  496. **************************************************************************/
  497.  
  498. LRESULT CDockingWindow::OnPaint(void)
  499. {
  500. PAINTSTRUCT ps;
  501. RECT        rc;
  502.  
  503. BeginPaint(m_hWnd, &ps);
  504.  
  505. GetClientRect(m_hWnd, &rc);
  506. SetTextColor(ps.hdc, RGB(0, 0, 0));
  507. SetBkMode(ps.hdc, TRANSPARENT);
  508. DrawText(ps.hdc, TEXT("IDockingWindow"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  509. EndPaint(m_hWnd, &ps);
  510.  
  511. return 0;
  512. }
  513.  
  514. /**************************************************************************
  515.  
  516.    CDockingWindow::OnCommand()
  517.    
  518. **************************************************************************/
  519.  
  520. LRESULT CDockingWindow::OnCommand(WPARAM wParam, LPARAM lParam)
  521. {
  522. /*
  523. Since this is a toolbar object, we need to forward all WM_COMMAND messages to 
  524. our assigned command window.
  525. */
  526. return SendMessage(m_hwndCommand, WM_COMMAND, wParam, lParam);
  527. }
  528.  
  529. /**************************************************************************
  530.  
  531.    CDockingWindow::FocusChange()
  532.    
  533. **************************************************************************/
  534.  
  535. void CDockingWindow::FocusChange(BOOL bFocus)
  536. {
  537. m_bFocus = bFocus;
  538.  
  539. //inform the input object site that the focus has changed
  540. IInputObjectSite  *pios;
  541.  
  542. if(SUCCEEDED(m_pSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pios)))
  543.    {
  544.    pios->OnFocusChangeIS((IDockingWindow*)this, bFocus);
  545.    pios->Release();
  546.    }
  547. }
  548.  
  549. /**************************************************************************
  550.  
  551.    CDockingWindow::OnSetFocus()
  552.    
  553. **************************************************************************/
  554.  
  555. LRESULT CDockingWindow::OnSetFocus(void)
  556. {
  557. FocusChange(TRUE);
  558.  
  559. m_pView->OnActivate(SVUIA_ACTIVATE_FOCUS);
  560.  
  561. return 0;
  562. }
  563.  
  564. /**************************************************************************
  565.  
  566.    CDockingWindow::OnKillFocus()
  567.    
  568. **************************************************************************/
  569.  
  570. LRESULT CDockingWindow::OnKillFocus(void)
  571. {
  572. FocusChange(FALSE);
  573.  
  574. m_pView->OnDeactivate();
  575.  
  576. return 0;
  577. }
  578.  
  579. /**************************************************************************
  580.  
  581.    CDockingWindow::NegotiateBorderSpace()
  582.    
  583. **************************************************************************/
  584.  
  585. BOOL CDockingWindow::NegotiateBorderSpace(IDockingWindowSite *pSite, LPCRECT prcBorder)
  586. {
  587. HRESULT        hr;
  588. BORDERWIDTHS   bwRequest = {0, 0, 0, 0};
  589.  
  590. bwRequest.top = TOOLBAR_HEIGHT;
  591.  
  592. hr = pSite->RequestBorderSpaceDW((IDockingWindow*)this, &bwRequest);
  593. if(SUCCEEDED(hr))
  594.    {
  595.    hr = pSite->SetBorderSpaceDW((IDockingWindow*)this, &bwRequest);
  596.    if(SUCCEEDED(hr))
  597.       {
  598.       RECT  rcTemp;
  599.  
  600.       if(!prcBorder)
  601.          {
  602.          hr = pSite->GetBorderDW((IDockingWindow*)this, &rcTemp);
  603.          if(SUCCEEDED(hr))
  604.             {
  605.             prcBorder = &rcTemp;
  606.             }
  607.          }
  608.          
  609.       if(prcBorder)
  610.          {
  611.          //set up our display rectangle
  612.          m_rcDisplay.left = prcBorder->left;
  613.          m_rcDisplay.top = prcBorder->top;
  614.          m_rcDisplay.right = prcBorder->right - prcBorder->left;
  615.          m_rcDisplay.bottom = bwRequest.top;
  616.          
  617.          return TRUE;
  618.          }
  619.       }
  620.    }
  621.  
  622. return FALSE;
  623. }
  624.  
  625.  
  626. #endif   //(_WIN32_IE >= 0x0400)