Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1716 lines
49 KiB

  1. #include "pch.hxx"
  2. #include <resource.h>
  3. #include "error.h"
  4. #include "treeview.h"
  5. #include "inpobj.h"
  6. #include "infcolum.h"
  7. #include "goptions.h"
  8. #include "strconst.h"
  9. #include "menuutil.h"
  10. #include "fldbar.h"
  11. #include "ourguid.h"
  12. #include "baui.h"
  13. CInfoColumn::~CInfoColumn()
  14. {
  15. DOUTL(1, TEXT("CInfoColulmn::~CInfoColumn: %x"), this);
  16. SafeRelease(m_pDwSite);
  17. SafeRelease(m_pTreeView);
  18. m_hwndParent = 0;
  19. if (m_hwndInfoColumn)
  20. {
  21. DestroyWindow(m_hwndInfoColumn);
  22. }
  23. //Destroy image list if we have one.
  24. if (m_himl)
  25. {
  26. ImageList_Destroy(m_himl);
  27. m_himl = 0;
  28. }
  29. if (m_hfIcon)
  30. DeleteObject(m_hfIcon);
  31. SafeRelease(m_pMsgrAb);
  32. }
  33. CInfoColumn::CInfoColumn ()
  34. {
  35. m_hwndInfoColumn = 0;
  36. m_hwndRebar = 0;
  37. m_fShow = 0;
  38. m_hwndParent = 0;
  39. m_CurFocus = 0;
  40. m_pDwSite = 0;
  41. m_cRef = 1;
  42. m_xWidth = DwGetOption(OPT_TREEWIDTH);
  43. m_himl = 0;
  44. m_pTreeView = 0;
  45. m_pMsgrAb = 0;
  46. m_hfIcon = NULL;
  47. m_fRebarDragging = FALSE;
  48. m_pFolderBar = NULL;
  49. m_cVisibleBands = 0;
  50. ZeroMemory(m_BandList, sizeof(m_BandList));
  51. ZeroMemory(m_CacheCmdTarget, sizeof(m_CacheCmdTarget));
  52. m_fDragging = FALSE;
  53. }
  54. HRESULT CInfoColumn::QueryInterface(REFIID riid, LPVOID * ppvObj)
  55. {
  56. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IOleWindow)
  57. || IsEqualIID(riid, IID_IDockingWindow))
  58. {
  59. *ppvObj = (IDockingWindow*)this;
  60. m_cRef++;
  61. DOUTL(2, TEXT("CInfoColumn::QI(IID_IDockingWindow) called. _cRef=%d"), m_cRef);
  62. return S_OK;
  63. }
  64. else if (IsEqualIID(riid, IID_IInputObject))
  65. {
  66. *ppvObj = (IInputObject*)this;
  67. m_cRef++;
  68. DOUTL(2, TEXT("CInfoColumn::QI(IID_IInputObject) called. _cRef=%d"), m_cRef);
  69. return S_OK;
  70. }
  71. else if (IsEqualIID(riid, IID_IObjectWithSite))
  72. {
  73. *ppvObj = (IObjectWithSite*)this;
  74. m_cRef++;
  75. DOUTL(2, TEXT("CInfoColumn::QI(IID_IObjectWithSite) called. _cRef=%d"), m_cRef);
  76. return S_OK;
  77. }
  78. else if (IsEqualIID(riid, IID_IInputObjectSite))
  79. {
  80. *ppvObj = (IInputObjectSite*)this;
  81. m_cRef++;
  82. DOUTL(2, TEXT("CInfoColumn::QI(IID_IInputObjectSite) called. _cRef=%d"), m_cRef);
  83. return S_OK;
  84. }
  85. else if (IsEqualIID(riid, IID_IOleCommandTarget))
  86. {
  87. *ppvObj = (IOleCommandTarget*)this;
  88. m_cRef++;
  89. DOUTL(2, TEXT("CInfoColumn::QI(IID_IOleCommandTarget) called. _cRef=%d"), m_cRef);
  90. return S_OK;
  91. }
  92. *ppvObj = 0;
  93. return E_NOINTERFACE;
  94. }
  95. ULONG CInfoColumn::AddRef()
  96. {
  97. m_cRef++;
  98. DOUTL(4, TEXT("CInfoColumn::AddRef() - m_cRef = %d"), m_cRef);
  99. return m_cRef;
  100. }
  101. ULONG CInfoColumn::Release()
  102. {
  103. DOUTL(4, TEXT("CInfoColumn::Release() - m_cRef = %d"), m_cRef);
  104. if (--m_cRef == 0)
  105. {
  106. delete this;
  107. return 0;
  108. }
  109. return m_cRef;
  110. }
  111. //
  112. // FUNCTION: CInfoColumn::GetWindow()
  113. //
  114. // PURPOSE: Returns the window handle of the top side rebar.
  115. //
  116. HRESULT CInfoColumn::GetWindow(HWND * lphwnd)
  117. {
  118. if (m_hwndRebar)
  119. {
  120. *lphwnd = m_hwndRebar;
  121. return (S_OK);
  122. }
  123. else
  124. {
  125. *lphwnd = 0;
  126. return (E_FAIL);
  127. }
  128. }
  129. HRESULT CInfoColumn::ContextSensitiveHelp(BOOL fEnterMode)
  130. {
  131. return (E_NOTIMPL);
  132. }
  133. #define INFOCOLUMNCLASS TEXT("InfoColumn")
  134. HRESULT CInfoColumn::CreateInfoColumn(BOOL fVisible)
  135. {
  136. if (m_hwndInfoColumn)
  137. return (hrAlreadyExists);
  138. m_hwndInfoColumn = CreateWindowEx(WS_EX_CONTROLPARENT, INFOCOLUMNCLASS, 0,
  139. WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (fVisible ? WS_VISIBLE : 0),
  140. 0, 0, 100, 200, m_hwndParent, (HMENU) 0, g_hInst, this);
  141. if (!m_hwndInfoColumn)
  142. {
  143. DWORD err;
  144. err = GetLastError();
  145. AssertSz(0, _T("CInfoColumn::CreateInfoColumn() - Failed to create a window"));
  146. return E_FAIL;
  147. }
  148. return S_OK;
  149. }
  150. //
  151. // FUNCTION: CInfoColumn::InfoColumnWndProc()
  152. //
  153. // PURPOSE: Handles messages sent to the InfoColumn root window.
  154. //
  155. LRESULT CALLBACK EXPORT_16 CInfoColumn::InfoColumnWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  156. {
  157. CInfoColumn *pInfoColumn = 0;
  158. if (uMsg == WM_NCCREATE)
  159. {
  160. pInfoColumn = (CInfoColumn*)((LPCREATESTRUCT) lParam)->lpCreateParams;
  161. SetWindowLong(hwnd, GWL_USERDATA, (LPARAM)pInfoColumn);
  162. }
  163. else
  164. {
  165. pInfoColumn = (CInfoColumn*)GetWindowLong(hwnd, GWL_USERDATA);
  166. }
  167. Assert (pInfoColumn);
  168. return pInfoColumn->PrivateProcessing(hwnd, uMsg, wParam, lParam);
  169. }
  170. //IDockingWindow::ShowDw
  171. HRESULT CInfoColumn::ShowDW(BOOL fShow)
  172. {
  173. HRESULT hres = S_OK;
  174. int i = 0,
  175. j = 0;
  176. m_fShow = fShow;
  177. // Check to see if our window has been created yet. If not, do that first.
  178. if (!m_hwndInfoColumn && m_pDwSite)
  179. {
  180. m_hwndParent = 0;
  181. hres = m_pDwSite->GetWindow(&m_hwndParent);
  182. if (SUCCEEDED(hres))
  183. {
  184. #ifndef WIN16 // WNDCLASSEX
  185. WNDCLASSEX wc;
  186. #else
  187. WNDCLASS wc;
  188. #endif
  189. // Check to see if we need to register our window class
  190. #ifndef WIN16
  191. wc.cbSize = sizeof(WNDCLASSEX);
  192. if (!GetClassInfoEx(g_hInst, INFOCOLUMNCLASS, &wc))
  193. #else
  194. if (!GetClassInfo(g_hInst, INFOCOLUMNCLASS, &wc))
  195. #endif
  196. {
  197. wc.style = 0;
  198. wc.lpfnWndProc = InfoColumnWndProc;
  199. wc.cbClsExtra = 0;
  200. #ifndef WIN16
  201. wc.cbWndExtra = 0;
  202. #else
  203. wc.cbWndExtra = 4;
  204. #endif
  205. wc.hInstance = g_hInst;
  206. wc.hCursor = LoadCursor(0, IDC_SIZEWE);
  207. wc.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);
  208. wc.lpszMenuName = 0;
  209. wc.lpszClassName = INFOCOLUMNCLASS;
  210. wc.hIcon = 0;
  211. #ifndef WIN16
  212. wc.hIconSm = 0;
  213. RegisterClassEx(&wc);
  214. #else
  215. RegisterClass(&wc);
  216. #endif
  217. }
  218. hres = CreateInfoColumn(fShow);
  219. if (FAILED(hres))
  220. return E_FAIL;
  221. }
  222. m_hwndRebar = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_CONTROLPARENT, REBARCLASSNAME, 0,
  223. RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_DBLCLKTOGGLE | RBS_FIXEDORDER
  224. | WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  225. CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_VERT, 0, 0, 0, 0,
  226. m_hwndInfoColumn, (HMENU)0, g_hInst, 0);
  227. if (!m_hwndRebar)
  228. {
  229. DestroyWindow(m_hwndInfoColumn);
  230. return E_FAIL;
  231. }
  232. hres = CreateBands();
  233. Assert(SUCCEEDED(hres));
  234. GetFontParams();
  235. //SendMessage(m_hwndRebar, RB_SETEXTENDEDSTYLE, RBS_EX_OFFICE9, RBS_EX_OFFICE9);
  236. }
  237. // Resize the rebar based on it's new hidden / visible state and also
  238. // show or hide the window.
  239. if (m_hwndInfoColumn)
  240. {
  241. /*
  242. if(fShow)
  243. {
  244. //If #of visible bands is zero, this means we were hidden before in options.
  245. if (!m_cVisibleBands)
  246. ShowAllBands();
  247. }
  248. else
  249. {
  250. //We are being hidden
  251. m_cVisibleBands = 0;
  252. }
  253. */
  254. ResizeBorderDW(0, 0, FALSE);
  255. ShowWindow(m_hwndInfoColumn, fShow ? SW_SHOW : SW_HIDE);
  256. hres = S_OK;
  257. }
  258. return hres;
  259. }
  260. void CInfoColumn::ShowAllBands()
  261. {
  262. int Count;
  263. REBARBANDINFO rbbinfo;
  264. Count = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  265. m_cVisibleBands = Count;
  266. for (--Count; Count >= 0; Count--)
  267. {
  268. ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
  269. rbbinfo.cbSize = sizeof(REBARBANDINFO);
  270. rbbinfo.fMask = RBBIM_STYLE;
  271. SendMessage(m_hwndRebar, RB_GETBANDINFO, Count, (LPARAM)&rbbinfo);
  272. rbbinfo.fStyle &= ~RBBS_HIDDEN;
  273. SendMessage(m_hwndRebar, RB_SETBANDINFO, Count, (LPARAM)&rbbinfo);
  274. }
  275. }
  276. HRESULT CInfoColumn::AddMsgrAb(DWORD dwSize, BOOL fVisible)
  277. {
  278. HRESULT hres = E_FAIL;
  279. if(!fVisible)
  280. return hres;
  281. hres = CreateMsgrAbCtrl(&m_pMsgrAb);
  282. if (SUCCEEDED(hres))
  283. {
  284. IInputObject *pObj;
  285. if (SUCCEEDED(hres = m_pMsgrAb->QueryInterface(IID_IInputObject, (LPVOID*)&pObj)))
  286. {
  287. if (SUCCEEDED(hres = AddObject(pObj, m_fShow)))
  288. {
  289. REBARBANDINFO bandinfo = {0};
  290. IOleWindow *pOleWindow;
  291. if (SUCCEEDED(m_pMsgrAb->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWindow)))
  292. {
  293. if (SUCCEEDED(pOleWindow->GetWindow(&bandinfo.hwndChild)))
  294. {
  295. char BandTitle[CCHMAX_STRINGRES];
  296. ZeroMemory(BandTitle, sizeof (BandTitle));
  297. if (g_hLocRes)
  298. LoadString(g_hLocRes, idsABBandTitle, BandTitle, sizeof(BandTitle));
  299. bandinfo.cbSize = sizeof (REBARBANDINFO);
  300. bandinfo.fMask = RBBIM_CHILD | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE |
  301. RBBIM_CHILDSIZE | RBBIM_TEXT | RBBIM_LPARAM;
  302. bandinfo.fStyle = RBBS_VARIABLEHEIGHT | (fVisible ? 0 : RBBS_HIDDEN);
  303. bandinfo.wID = ICBLAB;
  304. //Height
  305. bandinfo.cx = dwSize;
  306. bandinfo.cxMinChild = 0;
  307. //Width
  308. bandinfo.cyMinChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
  309. bandinfo.cyChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
  310. bandinfo.cyMaxChild = MAX_WIDTH;
  311. bandinfo.lpText = BandTitle;
  312. IDropDownFldrBar *pddf;
  313. m_pMsgrAb->QueryInterface(IID_IDropDownFldrBar, (void**)&pddf);
  314. bandinfo.lParam = (LPARAM)pddf;
  315. SendMessage(m_hwndRebar, RB_INSERTBAND, -1, (LPARAM)&bandinfo);
  316. if (fVisible)
  317. ++m_cVisibleBands;
  318. hres = S_OK;
  319. }
  320. pOleWindow->Release();
  321. }
  322. }
  323. }
  324. if (m_pMsgrAb->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_CacheCmdTarget[ITB_BUDDYADDRBOOK - ITB_INFOCOL_BASE]) != S_OK)
  325. {
  326. m_CacheCmdTarget[ITB_BUDDYADDRBOOK - ITB_INFOCOL_BASE] = NULL;
  327. }
  328. }
  329. return hres;
  330. }
  331. void CInfoColumn::GetFontParams()
  332. {
  333. //Get the Icon font and save it
  334. ICONMETRICS icm;
  335. icm.cbSize = sizeof(ICONMETRICS);
  336. SystemParametersInfo(SPI_GETICONMETRICS,
  337. sizeof(ICONMETRICS),
  338. (LPVOID) &icm, FALSE);
  339. if (m_hfIcon)
  340. DeleteObject(m_hfIcon);
  341. m_hfIcon = CreateFontIndirect(&(icm.lfFont));
  342. if (m_hfIcon)
  343. {
  344. SendMessage(m_hwndRebar, WM_SETFONT, (WPARAM) m_hfIcon, MAKELPARAM(TRUE, 0));
  345. }
  346. }
  347. //
  348. // FUNCTION: CInfoColumn::CloseDW()
  349. //
  350. // PURPOSE: Destroys the InfoColumnWindow.
  351. //
  352. //IDockingWindow::CloseDW
  353. HRESULT CInfoColumn::CloseDW(DWORD dwReserved)
  354. {
  355. IObjectWithSite *pObject = 0;
  356. // Save our settings before we close anything
  357. SaveSettings();
  358. //Go through the list of objects and deactivate them.
  359. for (DWORD index = 0; index < IC_MAX_OBJECTS; index++)
  360. {
  361. if (m_BandList[index].pBandObj)
  362. {
  363. m_BandList[index].pBandObj->UIActivateIO(FALSE, 0);
  364. if (SUCCEEDED(m_BandList[index].pBandObj->QueryInterface(IID_IObjectWithSite, (LPVOID *) &pObject)))
  365. {
  366. pObject->SetSite(0);
  367. pObject->Release();
  368. }
  369. SafeRelease(m_BandList[index].pBandObj);
  370. }
  371. SafeRelease(m_CacheCmdTarget[index]);
  372. }
  373. //Go through the bands and release lParam pointer
  374. CleanupLParam();
  375. if (m_pTreeView)
  376. {
  377. m_pTreeView->SetSite(0);
  378. m_pTreeView->DeInit();
  379. }
  380. SafeRelease(m_pTreeView);
  381. SafeRelease(m_CurFocus);
  382. if (m_hwndInfoColumn)
  383. {
  384. DestroyWindow(m_hwndInfoColumn);
  385. m_hwndInfoColumn = 0;
  386. }
  387. SafeRelease(m_CurFocus);
  388. return S_OK;
  389. }
  390. void CInfoColumn::CleanupLParam()
  391. {
  392. int count = 0;
  393. REBARBANDINFO rbbinfo;
  394. count = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  395. for (--count; count >= 0; count--)
  396. {
  397. ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
  398. rbbinfo.cbSize = sizeof(REBARBANDINFO);
  399. rbbinfo.fMask = RBBIM_LPARAM;
  400. SendMessage(m_hwndRebar, RB_GETBANDINFO, count, (LPARAM)&rbbinfo);
  401. if (rbbinfo.lParam)
  402. {
  403. ((IDropDownFldrBar*)rbbinfo.lParam)->Release();
  404. }
  405. }
  406. }
  407. //
  408. // FUNCTION: CInfoColumn::ResizeBorderDW()
  409. //
  410. // PURPOSE: This is called by the browser or dockwindow site when InfoColumn needs to resize.
  411. // The Infocolumn in return figures out how much border space will be required
  412. // from the parent frame and tells the parent to reserve that
  413. // space. The InfoColumn then resizes itself to those dimensions.
  414. //
  415. // PARAMETERS:
  416. // <in> prcBorder - Rectangle containing the border space for the
  417. // parent.
  418. // <in> punkToolbarSite - Pointer to the IDockingWindowSite that we are
  419. // part of.
  420. // <in> fReserved - Ignored.
  421. //
  422. // RETURN VALUE:
  423. // HRESULT
  424. //
  425. HRESULT CInfoColumn::ResizeBorderDW(LPCRECT prcBorder,
  426. IUnknown* punkToolbarSite,
  427. BOOL fReserved)
  428. {
  429. const DWORD c_cxResizeBorder = 3;
  430. HRESULT hres = S_OK;
  431. RECT rcRequest = { 0, 0, 0, 0 };
  432. // If we don't have a stored site pointer, we can't resize.
  433. if (!m_pDwSite)
  434. {
  435. AssertSz(m_pDwSite, _T("CInfoColumn::ResizeBorderDW() - Can't resize ")
  436. _T("without an IDockingWindowSite interface to call."));
  437. return (E_INVALIDARG);
  438. }
  439. // If we're visible, then calculate our border rectangle.
  440. if ((m_fShow) && (m_hwndInfoColumn))
  441. {
  442. if (!prcBorder)
  443. {
  444. RECT rcBorder;
  445. // Find out how big our parent's border space is
  446. m_pDwSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
  447. prcBorder = &rcBorder;
  448. Assert (prcBorder);
  449. }
  450. RECT rcRebar = {0};
  451. if (IsWindow(m_hwndRebar))
  452. {
  453. GetWindowRect(m_hwndRebar, &rcRebar);
  454. POINT pt;
  455. pt.x = rcRebar.right;
  456. pt.y = rcRebar.top;
  457. if (!ScreenToClient(m_hwndRebar, &pt))
  458. return E_FAIL;
  459. rcRebar.right = pt.x;
  460. }
  461. rcRequest.left = min(prcBorder->right - prcBorder->left, rcRebar.right + GetSystemMetrics(SM_CXFRAME));
  462. hres = m_pDwSite->RequestBorderSpaceDW((IDockingWindow*)this, &rcRequest);
  463. }
  464. m_pDwSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
  465. //We should set the border space before we set the window pos. Because resizing will call this function
  466. //again and the last SetBorderSpaceDW from us will be with the co-ordinates before re-sizing. This will be bad
  467. if (SUCCEEDED(hres) && m_hwndInfoColumn && m_fShow)
  468. {
  469. if (!SetWindowPos(m_hwndInfoColumn,
  470. 0,
  471. prcBorder->left,
  472. prcBorder->top,
  473. rcRequest.left,
  474. prcBorder->bottom - prcBorder->top,
  475. SWP_NOZORDER | SWP_NOACTIVATE))
  476. {
  477. AssertSz(FALSE, _T("Setwindowpos failed"));
  478. }
  479. }
  480. return hres;
  481. }
  482. //IObjectWithSite::SetSite
  483. HRESULT CInfoColumn::SetSite(IUnknown *pUnkSite)
  484. {
  485. if (m_pDwSite)
  486. {
  487. m_pDwSite->Release();
  488. m_pDwSite = 0;
  489. }
  490. if (pUnkSite)
  491. {
  492. if (FAILED(pUnkSite->QueryInterface(IID_IDockingWindowSite, (LPVOID*)&m_pDwSite)))
  493. {
  494. Assert (m_pDwSite);
  495. return E_FAIL;
  496. }
  497. }
  498. return S_OK;
  499. }
  500. //IObjectWithSite::GetSite
  501. HRESULT CInfoColumn::GetSite(REFIID riid, LPVOID *ppvSite)
  502. {
  503. return E_NOTIMPL;
  504. }
  505. ////////////////////////////////////////////////////////////////////////
  506. //
  507. // IInputObject
  508. //
  509. ////////////////////////////////////////////////////////////////////////
  510. HRESULT CInfoColumn::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  511. {
  512. if (fActivate)
  513. {
  514. UnkOnFocusChangeIS(m_pDwSite, (IInputObject*)this, TRUE);
  515. SetFocus(m_hwndRebar);
  516. }
  517. return S_OK;
  518. }
  519. HRESULT CInfoColumn::HasFocusIO(void)
  520. {
  521. if ( m_hwndRebar == 0 )
  522. return( S_FALSE );
  523. HWND hwndFocus = GetFocus();
  524. return ((hwndFocus && (hwndFocus == m_hwndRebar || IsChild(m_hwndRebar, hwndFocus)))) ? S_OK : S_FALSE;
  525. }
  526. HRESULT CInfoColumn::TranslateAcceleratorIO(LPMSG pMsg)
  527. {
  528. //Cycle through all the child windows and forward this if they have focus
  529. for (DWORD i = 0; i < IC_MAX_OBJECTS; i++)
  530. {
  531. if (m_BandList[i].pBandObj && UnkHasFocusIO(m_BandList[i].pBandObj) == S_OK)
  532. {
  533. if (UnkTranslateAcceleratorIO(m_BandList[i].pBandObj, pMsg) == S_OK)
  534. {
  535. return S_OK;
  536. }
  537. break;
  538. }
  539. }
  540. return (S_FALSE);
  541. }
  542. //IInputObjectSite
  543. HRESULT CInfoColumn::OnFocusChangeIS(IUnknown *punk, BOOL fSetFocus)
  544. {
  545. HRESULT hres = S_OK;
  546. IInputObject *prevfocus;
  547. if (punk)
  548. {
  549. if (fSetFocus)
  550. {
  551. prevfocus = m_CurFocus;
  552. HRESULT hres = punk->QueryInterface(IID_IInputObject, (LPVOID*)&m_CurFocus);
  553. if (FAILED(hres))
  554. {
  555. //reset Cur focus back to the previous one
  556. m_CurFocus = prevfocus;
  557. return hres;
  558. }
  559. //We should also let the browser know that we have the focus now
  560. IInputObjectSite *pinpsite;
  561. if (SUCCEEDED(m_pDwSite->QueryInterface(IID_IInputObjectSite, (LPVOID*)&pinpsite)))
  562. {
  563. pinpsite->OnFocusChangeIS((IDockingWindow*)this, fSetFocus);
  564. pinpsite->Release();
  565. }
  566. if (prevfocus)
  567. {
  568. prevfocus->UIActivateIO(FALSE, 0);
  569. prevfocus->Release();
  570. }
  571. hres = S_OK;
  572. }
  573. }
  574. else
  575. hres = E_INVALIDARG;
  576. return hres;
  577. }
  578. //IDropTarget
  579. HRESULT CInfoColumn::DragEnter( IDataObject *pDataObject,
  580. DWORD grfKeyState,
  581. POINTL pt,
  582. DWORD *pdwEffect)
  583. {
  584. return E_NOTIMPL;
  585. }
  586. HRESULT CInfoColumn::DragOver( DWORD grfKeyState,
  587. POINTL pt,
  588. DWORD *pdwEffect )
  589. {
  590. return E_NOTIMPL;
  591. }
  592. HRESULT CInfoColumn::DragLeave(void)
  593. {
  594. return E_NOTIMPL;
  595. }
  596. STDMETHODIMP CInfoColumn::Drop( IDataObject *pDataObject,
  597. DWORD grfKeyState,
  598. POINTL pt,
  599. DWORD *pdwEffect)
  600. {
  601. return E_NOTIMPL;
  602. }
  603. ////////////////////////////////////////////////////////////////////////
  604. //
  605. // Private Methods
  606. //
  607. ////////////////////////////////////////////////////////////////////////
  608. LRESULT CInfoColumn::PrivateProcessing(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  609. {
  610. switch (msg)
  611. {
  612. HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
  613. HANDLE_MSG(hwnd, WM_LBUTTONDOWN, OnLButtonDown);
  614. HANDLE_MSG(hwnd, WM_MOUSEMOVE, OnMouseMove);
  615. HANDLE_MSG(hwnd, WM_LBUTTONUP, OnLButtonUp);
  616. HANDLE_MSG(hwnd, WM_SIZE, OnSize);
  617. HANDLE_MSG(hwnd, WM_CONTEXTMENU, OnContextMenu);
  618. case WM_NOTIFY:
  619. return OnNotify(hwnd, wParam, (LPNMHDR) lParam);
  620. case WM_NCDESTROY:
  621. RevokeDragDrop(hwnd);
  622. SetWindowLong(hwnd, GWL_USERDATA, 0);
  623. m_hwndInfoColumn = 0;
  624. break;
  625. case WM_SETFOCUS:
  626. if (m_hwndRebar && ((HWND)wParam) != m_hwndRebar)
  627. {
  628. SetFocus(m_hwndRebar);
  629. }
  630. UnkOnFocusChangeIS(m_pDwSite, (IDockingWindow*)this, TRUE);
  631. return 0;
  632. case WMR_CLICKOUTSIDE:
  633. {
  634. BOOL fHide = FALSE;
  635. if (wParam == CLK_OUT_KEYBD || wParam == CLK_OUT_DEACTIVATE)
  636. fHide = TRUE;
  637. else if (wParam == CLK_OUT_MOUSE)
  638. fHide = !IsOurWindow((HWND)lParam);
  639. //fHide = ((HWND) lParam != m_hwndRebar && (HWND) lParam != m_hwndInfoColumn);
  640. if (fHide)
  641. m_pFolderBar->KillScopeDropDown();
  642. return (fHide);
  643. }
  644. }
  645. return DefWindowProc(hwnd, msg, wParam, lParam);
  646. }
  647. BOOL CInfoColumn::IsOurWindow(HWND hwnd)
  648. {
  649. BOOL bRet = FALSE;
  650. if ((hwnd != m_hwndInfoColumn) && (hwnd != m_hwndRebar))
  651. {
  652. int BandCount;
  653. REBARBANDINFO rbbinfo;
  654. BandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  655. for (--BandCount; BandCount >= 0; BandCount--)
  656. {
  657. ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
  658. rbbinfo.cbSize = sizeof(REBARBANDINFO);
  659. rbbinfo.fMask = RBBIM_CHILD;
  660. SendMessage(m_hwndRebar, RB_GETBANDINFO, BandCount, (LPARAM)&rbbinfo);
  661. if ((rbbinfo.hwndChild == hwnd) ||
  662. (IsChild(rbbinfo.hwndChild, hwnd)))
  663. {
  664. bRet = TRUE;
  665. break;
  666. }
  667. }
  668. }
  669. else
  670. {
  671. bRet = TRUE;
  672. }
  673. return bRet;
  674. }
  675. void CInfoColumn::OnLButtonDown(HWND hwnd,
  676. BOOL fDoubleClick,
  677. int x,
  678. int y,
  679. UINT keyFlags)
  680. {
  681. if ((!m_fRebarDragging) && (GetParent(m_hwndInfoColumn) == m_hwndParent))
  682. {
  683. // Capture the mouse
  684. SetCapture(m_hwndInfoColumn);
  685. // Start dragging
  686. m_fDragging = TRUE;
  687. }
  688. }
  689. void CInfoColumn::OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
  690. {
  691. HCURSOR hcur;
  692. POINT pt = {x, y};
  693. RECT rcClient;
  694. // If we're dragging, update the the window sizes
  695. if (m_fDragging)
  696. {
  697. // Make sure the tree is still a little bit visible
  698. if (x > 32)
  699. {
  700. SetDwOption(OPT_TREEWIDTH, x, 0, 0);
  701. ResizeBands(x - GetSystemMetrics(SM_CXFRAME));
  702. ResizeBorderDW(0, 0, FALSE);
  703. }
  704. }
  705. if(m_fRebarDragging)
  706. {
  707. //This is a temporary hack while the shell team fixes the RB_FIXEDORDER style in their code.
  708. //BUG#12591
  709. //This is bug has been fixed and verified as of 7/14/98. Hence removing the hack
  710. //if (y >= 5)
  711. SendMessage(m_hwndRebar, RB_DRAGMOVE, 0, MAKELPARAM(1, y));
  712. }
  713. }
  714. void CInfoColumn::OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
  715. {
  716. if (m_fDragging)
  717. {
  718. ReleaseCapture();
  719. m_fDragging = FALSE;
  720. }
  721. if (m_fRebarDragging)
  722. {
  723. m_fRebarDragging = FALSE;
  724. SendMessage(m_hwndRebar, RB_ENDDRAG, 0, 0);
  725. if (GetCapture() == hwnd)
  726. {
  727. ReleaseCapture();
  728. }
  729. }
  730. }
  731. void CInfoColumn::ResizeBands(int cx)
  732. {
  733. UINT uBandCount;
  734. UINT Index;
  735. REBARBANDINFO rbbinfo = {0};
  736. uBandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  737. for (Index = 0; Index < uBandCount; Index++)
  738. {
  739. //We do this in order to get CxMinChild. Execpt for OE TOday band this value
  740. //is set to zero at this point of time.
  741. rbbinfo.cbSize = sizeof(REBARBANDINFO);
  742. rbbinfo.fMask = RBBIM_CHILDSIZE;
  743. SendMessage(m_hwndRebar, RB_GETBANDINFO, Index, (LPARAM)&rbbinfo);
  744. rbbinfo.cyChild = cx;
  745. rbbinfo.cyMinChild = cx;
  746. SendMessage(m_hwndRebar, RB_SETBANDINFO, Index, (LPARAM)&rbbinfo);
  747. }
  748. }
  749. BOOL CInfoColumn::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
  750. {
  751. REBARINFO rebarinfo;
  752. #ifdef NEVER
  753. m_himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idbInfoColumn), 16, 0, RGB(255, 0, 255));
  754. rebarinfo.cbSize = sizeof (REBARINFO);
  755. rebarinfo.fMask = RBIM_IMAGELIST;
  756. rebarinfo.himl = m_himl;
  757. SendMessage (m_hwndRebar, RB_SETBARINFO, 0, (LPARAM)&rebarinfo);
  758. #endif NEVER
  759. RegisterDragDrop(hwnd, this);
  760. return TRUE;
  761. }
  762. void CInfoColumn::OnSize(HWND hwnd, UINT state, int cxClient, int cyClient)
  763. {
  764. if (m_hwndRebar && IsWindow(m_hwndRebar))
  765. {
  766. if (m_hwndParent != GetParent(m_hwndInfoColumn))
  767. {
  768. //This is being called by Folder Bar
  769. ResizeBands(cxClient);
  770. }
  771. cxClient = cxClient - GetSystemMetrics(SM_CXFRAME);
  772. if (!SetWindowPos(m_hwndRebar, 0, 0, 0,
  773. cxClient,
  774. cyClient,
  775. SWP_NOZORDER | SWP_NOACTIVATE))
  776. DWORD err = GetLastError();
  777. }
  778. }
  779. LRESULT CInfoColumn::OnNotify(HWND hwnd, WPARAM wParam, LPNMHDR lpnmh)
  780. {
  781. LRESULT retval = 0;
  782. switch (lpnmh->code)
  783. {
  784. case RBN_BEGINDRAG:
  785. retval = OnICBeginDrag((LPNMREBAR)lpnmh);
  786. break;
  787. case RBN_LAYOUTCHANGED:
  788. retval = TRUE;
  789. break;
  790. case RBN_HEIGHTCHANGE:
  791. if (m_hwndParent == GetParent (m_hwndInfoColumn))
  792. ResizeBorderDW(0, 0, FALSE);
  793. retval = TRUE;
  794. break;
  795. case NM_KILLFOCUS:
  796. if (m_pFolderBar)
  797. m_pFolderBar->KillScopeDropDown();
  798. break;
  799. case NM_SETFOCUS:
  800. UnkOnFocusChangeIS(m_pDwSite, (IDockingWindow*)this, TRUE);
  801. break;
  802. }
  803. return retval;
  804. }
  805. LRESULT CInfoColumn::OnICBeginDrag(LPNMREBAR pnm)
  806. {
  807. SetCapture(m_hwndInfoColumn);
  808. SendMessage(m_hwndRebar, RB_BEGINDRAG, pnm->uBand, (LPARAM)-2);
  809. m_fRebarDragging = TRUE;
  810. return 1;
  811. }
  812. HRESULT CInfoColumn::HrInit(IAthenaBrowser *pBrowser,
  813. ITreeViewNotify *ptvNotify)
  814. {
  815. HRESULT hres = E_FAIL;
  816. if (pBrowser && ptvNotify)
  817. {
  818. if(m_pTreeView = new CTreeView(ptvNotify))
  819. //Add the treeview before OEToday since we navigate to the front page using TreeView.
  820. hres = m_pTreeView->HrInit(0, pBrowser);
  821. }
  822. return hres;
  823. }
  824. HRESULT CInfoColumn::AddTreeView(DWORD dwSize, BOOL fVisible)
  825. {
  826. REBARBANDINFO bandinfo = {0};
  827. RECT rctree;
  828. int cxFrame;
  829. int iWidth;
  830. char BandTitle[CCHMAX_STRINGRES];
  831. HRESULT hres = E_FAIL;
  832. IInputObject *pObj;
  833. if (SUCCEEDED(m_pTreeView->QueryInterface(IID_IInputObject, (LPVOID*)&pObj)))
  834. {
  835. if (SUCCEEDED(hres = AddObject(pObj, m_fShow)))
  836. {
  837. cxFrame = GetSystemMetrics(SM_CXFRAME);
  838. iWidth = m_xWidth - cxFrame;
  839. if (SUCCEEDED(m_pTreeView->GetWindow(&bandinfo.hwndChild)))
  840. {
  841. /*
  842. if (dwSize == 0)
  843. {
  844. //We make the TreeView atleast half of the InfoColumn window. Starting up
  845. //with the TreeView minimized is confusing out people
  846. GetClientRect(m_hwndInfoColumn, &rctree);
  847. dwSize = rctree.bottom / 2;
  848. }
  849. */
  850. if (g_hLocRes)
  851. {
  852. LoadString(g_hLocRes, idsMNBandTitle, BandTitle, sizeof(BandTitle));
  853. }
  854. bandinfo.cbSize = sizeof (REBARBANDINFO);
  855. bandinfo.fMask = RBBIM_CHILD | RBBIM_STYLE | RBBIM_ID | RBBIM_SIZE
  856. | RBBIM_CHILDSIZE | RBBIM_TEXT | RBBIM_LPARAM;
  857. bandinfo.fStyle = RBBS_VARIABLEHEIGHT | (fVisible ? 0 : RBBS_HIDDEN);
  858. bandinfo.wID = ICTREEVIEW;
  859. //Height
  860. bandinfo.cx = dwSize;
  861. //Width
  862. bandinfo.cyMinChild = (UINT)iWidth;
  863. bandinfo.cyChild = (UINT)iWidth;
  864. bandinfo.cyMaxChild = MAX_WIDTH;
  865. bandinfo.lpText = BandTitle;
  866. IDropDownFldrBar *pddf;
  867. m_pTreeView->QueryInterface(IID_IDropDownFldrBar, (void**)&pddf);
  868. bandinfo.lParam = (LPARAM)pddf;
  869. SendMessage(m_hwndRebar, RB_INSERTBAND, -1, (LPARAM)&bandinfo);
  870. if (fVisible)
  871. {
  872. ++m_cVisibleBands;
  873. }
  874. hres = S_OK;
  875. }
  876. }
  877. }
  878. if (m_pTreeView->QueryInterface(IID_IOleCommandTarget, (LPVOID*)&m_CacheCmdTarget[ITB_TREE - ITB_INFOCOL_BASE]) != S_OK)
  879. {
  880. m_CacheCmdTarget[ITB_TREE - ITB_INFOCOL_BASE] = NULL;
  881. }
  882. return hres;
  883. }
  884. void CInfoColumn::AddOETodayBand(DWORD dwSize, BOOL fVisible)
  885. {
  886. REBARBANDINFO bandinfo = {0};
  887. char BandTitle[CCHMAX_STRINGRES] = {0};
  888. //Add Outlook Express band
  889. if (g_hLocRes)
  890. {
  891. LoadString(g_hLocRes, idsOEBandTitle, BandTitle, sizeof(BandTitle));
  892. }
  893. bandinfo.cbSize = sizeof (REBARBANDINFO);
  894. bandinfo.fMask = RBBIM_STYLE | RBBIM_ID | RBBIM_TEXT | RBBIM_SIZE
  895. | RBBIM_CHILDSIZE | RBBIM_TEXT;
  896. bandinfo.fStyle = RBBS_FIXEDSIZE | (fVisible ? 0 : RBBS_HIDDEN);
  897. bandinfo.cyMinChild = m_xWidth - GetSystemMetrics(SM_CXFRAME);
  898. bandinfo.cxMinChild = 0;
  899. bandinfo.cx = 0;
  900. bandinfo.wID = ICOETODAY;
  901. bandinfo.lpText = BandTitle;
  902. SendMessage(m_hwndRebar, RB_INSERTBAND, (UINT) -1, (LPARAM)&bandinfo);
  903. if (fVisible)
  904. ++m_cVisibleBands;
  905. }
  906. CTreeView* CInfoColumn::GetTreeView()
  907. {
  908. Assert(m_pTreeView);
  909. m_pTreeView->AddRef();
  910. return m_pTreeView;
  911. }
  912. HRESULT CInfoColumn::AddObject(IInputObject *pinpobj, DWORD fShow)
  913. {
  914. DWORD dwIndex;
  915. HRESULT hres;
  916. if (SUCCEEDED(FindBandListIndex(&dwIndex)))
  917. {
  918. m_BandList[dwIndex].fShow = fShow;
  919. m_BandList[dwIndex].pBandObj = pinpobj;
  920. IObjectWithSite *pObject = 0;
  921. hres = pinpobj->QueryInterface(IID_IObjectWithSite, (LPVOID *) &pObject);
  922. if (SUCCEEDED(hres))
  923. {
  924. pObject->SetSite((IDockingWindow *) this);
  925. pObject->Release();
  926. }
  927. m_BandList[dwIndex].pBandObj->UIActivateIO(fShow, 0);
  928. hres = S_OK;
  929. }
  930. else
  931. hres = E_FAIL;
  932. return hres;
  933. }
  934. DWORD CInfoColumn::FindBandObject(IInputObject *pinpobj)
  935. {
  936. if (pinpobj)
  937. {
  938. DWORD index;
  939. for (index = 0; index < IC_MAX_OBJECTS; index++)
  940. {
  941. if (pinpobj == m_BandList[index].pBandObj)
  942. return index;
  943. }
  944. }
  945. return INVALID_BAND_INDEX;
  946. }
  947. HRESULT CInfoColumn::FindBandListIndex(DWORD *pdwindex)
  948. {
  949. DWORD index;
  950. for (index = 0; index < IC_MAX_OBJECTS; index++)
  951. {
  952. if (!m_BandList[index].pBandObj)
  953. {
  954. *pdwindex = index;
  955. return S_OK;
  956. }
  957. }
  958. return E_FAIL;
  959. }
  960. BOOL CInfoColumn::CycleFocus(BOOL fReverse)
  961. {
  962. DWORD Index;
  963. BOOL fRet = FALSE;
  964. if (m_CurFocus)
  965. {
  966. Index = FindBandObject(m_CurFocus);
  967. if (fReverse)
  968. {
  969. Index--;
  970. }
  971. else
  972. {
  973. Index++;
  974. }
  975. fRet = SetCycledFocus(Index, fReverse);
  976. }
  977. return fRet;
  978. }
  979. BOOL CInfoColumn::CycleFocus(DWORD LastorFirst, BOOL fReverse)
  980. {
  981. DWORD Index;
  982. BOOL fRet = FALSE;
  983. if (LastorFirst == INFOCOLUMN_FIRST)
  984. {
  985. Index = GetFirstBand();
  986. fRet = SetCycledFocus(Index, fReverse);
  987. }
  988. else
  989. if (LastorFirst == INFOCOLUMN_LAST)
  990. {
  991. Index = GetLastBand();
  992. fRet = SetCycledFocus(Index, fReverse);
  993. }
  994. return fRet;
  995. }
  996. BOOL CInfoColumn::SetCycledFocus(DWORD Index, BOOL fReverse)
  997. {
  998. BOOL fRet = FALSE;
  999. if ((Index >= 0) && (Index < IC_MAX_OBJECTS) && m_BandList[Index].pBandObj)
  1000. {
  1001. IOleWindow *pOleWnd;
  1002. if (SUCCEEDED(m_BandList[Index].pBandObj->QueryInterface(IID_IOleWindow, (LPVOID*)&pOleWnd)))
  1003. {
  1004. HWND hwnd;
  1005. if (SUCCEEDED(pOleWnd->GetWindow(&hwnd)))
  1006. {
  1007. RECT Clientrc;
  1008. GetClientRect(hwnd, &Clientrc);
  1009. if (Clientrc.bottom)
  1010. {
  1011. SetFocus(hwnd);
  1012. fRet = TRUE;
  1013. }
  1014. else
  1015. {
  1016. fRet = SetCycledFocus(fReverse ? --Index : ++Index, fReverse);
  1017. }
  1018. }
  1019. pOleWnd->Release();
  1020. }
  1021. }
  1022. return fRet;
  1023. }
  1024. DWORD CInfoColumn::GetFirstBand()
  1025. {
  1026. DWORD Index;
  1027. for (Index = 0; Index < IC_MAX_OBJECTS; Index++)
  1028. {
  1029. if (m_BandList[Index].pBandObj)
  1030. {
  1031. break;
  1032. }
  1033. }
  1034. return Index;
  1035. }
  1036. DWORD CInfoColumn::GetLastBand()
  1037. {
  1038. DWORD Index;
  1039. for (Index = 0; Index < IC_MAX_OBJECTS; Index++)
  1040. {
  1041. if (!m_BandList[Index].pBandObj)
  1042. {
  1043. break;
  1044. }
  1045. }
  1046. return (--Index);
  1047. }
  1048. void CInfoColumn::ForwardMessages(UINT msg, WPARAM wParam, LPARAM lParam)
  1049. {
  1050. SendMessage(m_hwndRebar, msg, wParam, lParam);
  1051. for (DWORD Index = 0; Index < IC_MAX_OBJECTS; Index++)
  1052. {
  1053. if(m_BandList[Index].pBandObj)
  1054. {
  1055. IOleWindow *polewnd;
  1056. if(SUCCEEDED(m_BandList[Index].pBandObj->QueryInterface(IID_IOleWindow, (LPVOID*)&polewnd)))
  1057. {
  1058. HWND hwnd;
  1059. if (SUCCEEDED(polewnd->GetWindow(&hwnd)))
  1060. {
  1061. SendMessage(hwnd, msg, wParam, lParam);
  1062. }
  1063. }
  1064. polewnd->Release();
  1065. }
  1066. }
  1067. GetFontParams();
  1068. }
  1069. HRESULT CInfoColumn::SaveSettings(void)
  1070. {
  1071. HRESULT hr = E_FAIL;
  1072. DWORD iBand;
  1073. DWORD cBands;
  1074. HKEY hKey = 0;
  1075. HKEY hSubKey = 0;
  1076. REBARBANDINFO rbbi;
  1077. TCHAR szSubKey[CCHMAX_STRINGRES];
  1078. BOOL fVisible = TRUE;
  1079. DWORD dwDisposition = 0;
  1080. DWORD dwResult;
  1081. DWORD VersionID;
  1082. // If we don't have a rebar control, then there's nothing to save
  1083. if (!m_hwndRebar)
  1084. return (S_FALSE);
  1085. // Zero - init this structure
  1086. ZeroMemory(&rbbi, sizeof(REBARBANDINFO));
  1087. rbbi.cbSize = sizeof(REBARBANDINFO);
  1088. rbbi.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_SIZE | RBBIM_ID;
  1089. // Delete the old key so there's no leftover information
  1090. AthUserDeleteKey(c_szRegInfoColumn);
  1091. // Get the reg key we need
  1092. if (ERROR_SUCCESS != AthUserCreateKey(c_szRegInfoColumn, KEY_ALL_ACCESS, &hKey, &dwDisposition))
  1093. goto exit;
  1094. VersionID = LEFTPANE_VERSION;
  1095. AthUserSetValue(c_szRegInfoColumn, "Version", REG_BINARY, (const LPBYTE)&VersionID, sizeof(DWORD));
  1096. // Get the number of bands from the rebar
  1097. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1098. // Loop through bands we know about
  1099. for (iBand = 0; iBand < cBands; iBand++)
  1100. {
  1101. // Get the band information
  1102. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  1103. {
  1104. fVisible = !(rbbi.fStyle & RBBS_HIDDEN);
  1105. // Open a subkey for this one
  1106. wnsprintf(szSubKey, ARRAYSIZE(szSubKey),c_szRegICBand, iBand);
  1107. dwResult = RegCreateKeyEx(hKey, szSubKey, 0, 0, REG_OPTION_NON_VOLATILE,
  1108. KEY_ALL_ACCESS, 0, &hSubKey, &dwDisposition);
  1109. if (ERROR_SUCCESS == dwResult)
  1110. {
  1111. RegSetValueEx(hSubKey, c_szRegICBandID, 0, REG_DWORD, (const LPBYTE) &(rbbi.wID), sizeof(UINT));
  1112. RegSetValueEx(hSubKey, c_szRegICBandSize, 0, REG_DWORD, (const LPBYTE) &(rbbi.cx), sizeof(UINT));
  1113. RegSetValueEx(hSubKey, c_szRegICBandVisible, 0, REG_DWORD, (const LPBYTE) &fVisible, sizeof(BOOL));
  1114. RegCloseKey(hSubKey);
  1115. }
  1116. }
  1117. }
  1118. exit:
  1119. if (hKey)
  1120. RegCloseKey(hKey);
  1121. return (hr);
  1122. }
  1123. HRESULT CInfoColumn::CreateBands(void)
  1124. {
  1125. HRESULT hr;
  1126. HKEY hKey = 0;
  1127. HKEY hSubKey = 0;
  1128. DWORD iBand;
  1129. DWORD cBands = IC_MAX_OBJECTS;
  1130. TCHAR szSubKey[CCHMAX_STRINGRES];
  1131. LONG lResult;
  1132. DWORD dwType;
  1133. DWORD dwID;
  1134. DWORD dwHeight;
  1135. DWORD dwVisible;
  1136. DWORD cbData;
  1137. // First see if we have any persisted settings. If not, then
  1138. // create the default band set.
  1139. lResult = AthUserOpenKey(c_szRegInfoColumn, KEY_READ | KEY_QUERY_VALUE, &hKey);
  1140. if (lResult != ERROR_SUCCESS)
  1141. return CreateDefaultBands();
  1142. //See if the version numbers match
  1143. DWORD VersionID = 0;
  1144. cbData = sizeof(DWORD);
  1145. lResult = AthUserGetValue(c_szRegInfoColumn, "Version", &dwType, (LPBYTE)&VersionID, &cbData);
  1146. if ((lResult != ERROR_SUCCESS) || (VersionID != LEFTPANE_VERSION))
  1147. {
  1148. RegCloseKey(hKey);
  1149. hKey = 0;
  1150. return CreateDefaultBands();
  1151. }
  1152. // If we have saved information, figure out how many bands are saved
  1153. if (hKey)
  1154. {
  1155. RegQueryInfoKey(hKey, 0, 0, 0, &cBands, 0, 0, 0, 0, 0, 0, 0);
  1156. // If there are not any bands saved, then we use defaults
  1157. if (!cBands)
  1158. {
  1159. RegCloseKey(hKey);
  1160. hKey = 0;
  1161. hr = CreateDefaultBands();
  1162. goto exit;
  1163. }
  1164. }
  1165. // Loop through the bands in the registry
  1166. for (iBand = 0; iBand < cBands; iBand++)
  1167. {
  1168. // Open the band's subkey
  1169. wnsprintf(szSubKey,ARRAYSIZE(szSubKey), c_szRegICBand, iBand);
  1170. if (ERROR_SUCCESS == RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey))
  1171. {
  1172. // Read the band ID. If this ain't valid, we skip the whole band.
  1173. cbData = sizeof(DWORD);
  1174. lResult = RegQueryValueEx(hSubKey, c_szRegICBandID, 0, &dwType,
  1175. (LPBYTE) &dwID, &cbData);
  1176. if (lResult != ERROR_SUCCESS || dwID > IC_MAX_OBJECTS)
  1177. continue;
  1178. // Read the band height
  1179. lResult = RegQueryValueEx(hSubKey, c_szRegICBandSize, 0, &dwType,
  1180. (LPBYTE) &dwHeight, &cbData);
  1181. if (lResult != ERROR_SUCCESS)
  1182. dwHeight = 0;
  1183. // Read the visibility status
  1184. lResult = RegQueryValueEx(hSubKey, c_szRegICBandVisible, 0, &dwType,
  1185. (LPBYTE) &dwVisible, &cbData);
  1186. if (lResult != ERROR_SUCCESS)
  1187. dwVisible = TRUE;
  1188. // Now that we have all of this lovely information, create the
  1189. // band.
  1190. switch (dwID)
  1191. {
  1192. case ICOETODAY:
  1193. break;
  1194. case ICTREEVIEW:
  1195. AddTreeView(dwHeight, dwVisible);
  1196. break;
  1197. case ICBLAB:
  1198. AddMsgrAb(dwHeight, dwVisible);
  1199. break;
  1200. default:
  1201. AssertSz(FALSE, "CInfoColumn::CreateBands() - Unknown band ID.");
  1202. }
  1203. // Close the reg key
  1204. RegCloseKey(hSubKey);
  1205. }
  1206. }
  1207. hr = S_OK;
  1208. exit:
  1209. if (hKey)
  1210. RegCloseKey(hKey);
  1211. return (hr);
  1212. }
  1213. HRESULT CInfoColumn::CreateDefaultBands(void)
  1214. {
  1215. // Loop through the bands and create one of each
  1216. for (UINT id = 0; id < IC_MAX_OBJECTS; id++)
  1217. {
  1218. switch (id)
  1219. {
  1220. case ICOETODAY:
  1221. break;
  1222. case ICTREEVIEW:
  1223. {
  1224. //Poeple want to see the TreeView the first time they start up
  1225. RECT rctree = {0};
  1226. if (m_hwndInfoColumn)
  1227. {
  1228. GetClientRect(m_hwndInfoColumn, &rctree);
  1229. }
  1230. AddTreeView(rctree.bottom / 2);
  1231. break;
  1232. }
  1233. case ICBLAB:
  1234. AddMsgrAb();
  1235. break;
  1236. default:
  1237. AssertSz(FALSE, "CInfoColumn::CreateBands() - Unknown band ID.");
  1238. }
  1239. }
  1240. return (S_OK);
  1241. }
  1242. void CInfoColumn::OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
  1243. {
  1244. // Load the context menu
  1245. HMENU hMenu = LoadPopupMenu(IDR_INFOCOLUMN_POPUP);
  1246. if (!hMenu)
  1247. return;
  1248. // Loop through the bands and see which ones are visible
  1249. DWORD cBands, iBand;
  1250. REBARBANDINFO rbbi = {0};
  1251. rbbi.cbSize = sizeof(REBARBANDINFO);
  1252. rbbi.fMask = RBBIM_STYLE | RBBIM_ID;
  1253. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1254. for (iBand = 0; iBand < cBands; iBand++)
  1255. {
  1256. if (SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi))
  1257. {
  1258. if (!(rbbi.fStyle & RBBS_HIDDEN))
  1259. {
  1260. switch (rbbi.wID)
  1261. {
  1262. case ICBLAB:
  1263. CheckMenuItem(hMenu, ID_INFOCOLUMN_CONTACTS, MF_BYCOMMAND | MF_CHECKED);
  1264. break;
  1265. case ICTREEVIEW:
  1266. CheckMenuItem(hMenu, ID_INFOCOLUMN_FOLDER_LIST, MF_BYCOMMAND | MF_CHECKED);
  1267. break;
  1268. }
  1269. }
  1270. }
  1271. }
  1272. DWORD cmd;
  1273. cmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  1274. xPos, yPos, m_hwndInfoColumn, NULL);
  1275. if (cmd != 0)
  1276. {
  1277. switch (cmd)
  1278. {
  1279. case ID_INFOCOLUMN_CONTACTS:
  1280. if (m_pMsgrAb)
  1281. {
  1282. ShowHideBand(ICBLAB);
  1283. }
  1284. else
  1285. {
  1286. AddMsgrAb();
  1287. }
  1288. break;
  1289. case ID_INFOCOLUMN_FOLDER_LIST:
  1290. if (m_pTreeView)
  1291. {
  1292. ShowHideBand(ICTREEVIEW);
  1293. }
  1294. else
  1295. {
  1296. AddTreeView();
  1297. }
  1298. break;
  1299. }
  1300. }
  1301. //If none of the bands is visible, hide the InfoColumn too
  1302. if (!m_cVisibleBands)
  1303. {
  1304. //We can't afford to hide all the bands as it will shrink the Rebar window itself
  1305. //so we make all the bands visible, but hide the InfoColumn Window
  1306. ShowAllBands();
  1307. if (GetParent(m_hwndInfoColumn) != m_hwndParent && m_pFolderBar)
  1308. m_pFolderBar->KillScopeDropDown();
  1309. g_pBrowser->SetViewLayout(DISPID_MSGVIEW_FOLDERLIST, LAYOUT_POS_NA, FALSE, 0, 0);
  1310. }
  1311. }
  1312. void CInfoColumn::ShowHideBand(DWORD dwBandID)
  1313. {
  1314. REBARBANDINFO rbbi = {0};
  1315. DWORD cBands;
  1316. DWORD iBand;
  1317. rbbi.cbSize = sizeof(REBARBANDINFO);
  1318. rbbi.fMask = RBBIM_ID | RBBIM_STYLE;
  1319. // Find the band
  1320. cBands = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1321. for (iBand = 0; iBand < cBands; iBand++)
  1322. {
  1323. SendMessage(m_hwndRebar, RB_GETBANDINFO, iBand, (LPARAM) &rbbi);
  1324. if (rbbi.wID == dwBandID)
  1325. {
  1326. if (rbbi.fStyle & RBBS_HIDDEN)
  1327. {
  1328. rbbi.fStyle &= ~RBBS_HIDDEN;
  1329. ++m_cVisibleBands;
  1330. }
  1331. else
  1332. {
  1333. rbbi.fStyle |= RBBS_HIDDEN;
  1334. --m_cVisibleBands;
  1335. }
  1336. SendMessage(m_hwndRebar, RB_SETBANDINFO, iBand, (LPARAM) &rbbi);
  1337. return;
  1338. }
  1339. }
  1340. AssertSz(FALSE, "Failed to find the requested band.");
  1341. }
  1342. //Called by the Folder Bar as a drop down pane
  1343. HRESULT CInfoColumn::RegisterFlyOut(CFolderBar *pFolderBar)
  1344. {
  1345. Assert(m_pFolderBar == NULL);
  1346. //If all our bands are hidden then make all of them visible.
  1347. //This happens only when the user hides all the bands making the
  1348. //InfoColumn disappear, which causes the drop down to be visible
  1349. //from folder bar.
  1350. if (!m_cVisibleBands)
  1351. {
  1352. ShowAllBands();
  1353. }
  1354. m_pFolderBar = pFolderBar;
  1355. m_pFolderBar->AddRef();
  1356. RegisterChildren(pFolderBar, TRUE);
  1357. RegisterGlobalDropDown(m_hwndInfoColumn);
  1358. return S_OK;
  1359. }
  1360. HRESULT CInfoColumn::RevokeFlyOut(void)
  1361. {
  1362. if (m_pFolderBar)
  1363. {
  1364. m_pFolderBar->Release();
  1365. m_pFolderBar = NULL;
  1366. }
  1367. RegisterChildren(NULL, FALSE);
  1368. UnregisterGlobalDropDown(m_hwndInfoColumn);
  1369. return S_OK;
  1370. }
  1371. //Called by Folder Bar for drop down scope
  1372. HRESULT CInfoColumn::GetInfoColWnd(HWND * lphwnd)
  1373. {
  1374. if (m_hwndInfoColumn)
  1375. {
  1376. *lphwnd = m_hwndInfoColumn;
  1377. return (S_OK);
  1378. }
  1379. else
  1380. {
  1381. *lphwnd = 0;
  1382. return (E_FAIL);
  1383. }
  1384. }
  1385. HRESULT CInfoColumn::RegisterChildren(CFolderBar *pFolder, BOOL Register)
  1386. {
  1387. int BandCount;
  1388. REBARBANDINFO rbbinfo;
  1389. BandCount = SendMessage(m_hwndRebar, RB_GETBANDCOUNT, 0, 0);
  1390. for (--BandCount; BandCount >= 0; BandCount--)
  1391. {
  1392. ZeroMemory(&rbbinfo, sizeof(REBARBANDINFO));
  1393. rbbinfo.fMask = RBBIM_LPARAM;
  1394. SendMessage(m_hwndRebar, RB_GETBANDINFO, BandCount, (LPARAM)&rbbinfo);
  1395. if (rbbinfo.lParam)
  1396. {
  1397. if (Register)
  1398. ((IDropDownFldrBar*)rbbinfo.lParam)->RegisterFlyOut(pFolder);
  1399. else
  1400. ((IDropDownFldrBar*)rbbinfo.lParam)->RevokeFlyOut();
  1401. }
  1402. }
  1403. return S_OK;
  1404. }
  1405. HRESULT CInfoColumn::HasFocus(UINT itb)
  1406. {
  1407. HRESULT hres = S_FALSE;
  1408. IInputObject *pinpobj = NULL;
  1409. switch (itb)
  1410. {
  1411. case ITB_TREE:
  1412. if (m_pTreeView && SUCCEEDED(m_pTreeView->QueryInterface(IID_IInputObject, (void**)&pinpobj)))
  1413. {
  1414. hres = pinpobj->HasFocusIO();
  1415. }
  1416. break;
  1417. case ITB_BUDDYADDRBOOK:
  1418. if (m_pMsgrAb && SUCCEEDED(m_pMsgrAb->QueryInterface(IID_IInputObject, (void**)&pinpobj)))
  1419. {
  1420. hres = pinpobj->HasFocusIO();
  1421. }
  1422. break;
  1423. }
  1424. if (pinpobj)
  1425. pinpobj->Release();
  1426. return hres;
  1427. }
  1428. HRESULT STDMETHODCALLTYPE CInfoColumn::QueryStatus(const GUID *pguidCmdGroup,
  1429. ULONG cCmds,
  1430. OLECMD *prgCmds,
  1431. OLECMDTEXT *pCmdText)
  1432. {
  1433. // Always let all bands have a shot at this
  1434. for (UINT i = 0; i < IC_MAX_OBJECTS; i++)
  1435. {
  1436. // Check to see if we have a command target for this band.
  1437. if (m_CacheCmdTarget[i])
  1438. m_CacheCmdTarget[i]->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
  1439. }
  1440. return S_OK;
  1441. }
  1442. HRESULT STDMETHODCALLTYPE CInfoColumn::Exec(const GUID *pguidCmdGroup,
  1443. DWORD nCmdID,
  1444. DWORD nCmdExecOpt,
  1445. VARIANTARG *pvaIn,
  1446. VARIANTARG *pvaOut)
  1447. {
  1448. IOleCommandTarget *pcmdTarget = NULL;
  1449. HRESULT hr = S_FALSE;
  1450. // Loop through all the bands to see if this is their command
  1451. for (UINT i = 0; i < IC_MAX_OBJECTS; i++)
  1452. {
  1453. // Check to see if we have a command target for this band
  1454. if (m_CacheCmdTarget[i])
  1455. {
  1456. // See if the command belongs to this band
  1457. if (SUCCEEDED(hr = m_CacheCmdTarget[i]->Exec(pguidCmdGroup, nCmdID,
  1458. nCmdExecOpt, pvaIn, pvaOut)))
  1459. {
  1460. return (hr);
  1461. }
  1462. }
  1463. }
  1464. return (OLECMDERR_E_NOTSUPPORTED);
  1465. }