Click here to Skip to main content
15,886,780 members
Articles / Desktop Programming / WTL

Outlook Bar Control and Frame (WTL)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
27 Jun 2001 276.3K   7.1K   84  
An outlook control and framework that can be used in your WTL Application
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MAINFRM_H__5F15259F_10A4_11D5_A093_CB9BFECE0F30__INCLUDED_)
#define AFX_MAINFRM_H__5F15259F_10A4_11D5_A093_CB9BFECE0F30__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "atloutbarctrl.h"
#include "atloutbarsplit.h"
#include "OutlookCaptionBarView.h"

#define IDC_OUTLOOKK_TREE 1786

class CSplitterTestView : public CWindowImpl<CSplitterTestView>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg)
	{
		pMsg;
		return FALSE;
	}

	BEGIN_MSG_MAP(CSplitterTestView)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
	END_MSG_MAP()

	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL&
/*bHandled*/)
	{
		CPaintDC dc(m_hWnd);

      CRect rc;
      GetClientRect(&rc);

      CString name;
      GetWindowText(name.GetBuffer(MAX_PATH), MAX_PATH);
      name.ReleaseBuffer();

      dc.DrawText(name, name.GetLength(), rc, DT_CENTER | DT_VCENTER |
      DT_SINGLELINE);

		return 0;
	}
};

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
		public CMessageFilter, public CIdleHandler
{
public:
	DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

	CTreeViewCtrl m_tree;

	CCommandBarCtrl m_CmdBar;
	COutBarCtrl	wndBar;
	CImageList		imaLarge, imaSmall;
  COutlookSplitterWindow m_splitter;
  COutlookHorSplitterWindow m_PaneSplitter;
  COutlookCaptionBarView m_captionBar;
  CHorSplitterWindow m_HorizontalSplitter;
  COutlookSplitterWindow m_VerticalSplitter;
  CSplitterTestView  m_view1, m_view2, m_view3;
	CPaneContainer m_TreePane;
	HTREEITEM m_hConnections;
  int m_nIconStartIndex;
	BOOL m_bFolderState;

	virtual BOOL PreTranslateMessage(MSG* pMsg)
	{
		if(CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg))
			return TRUE;

		return FALSE;
	}

	virtual BOOL OnIdle()
	{
		UIUpdateToolBar();
		return FALSE;
	}

	BEGIN_MSG_MAP(CMainFrame)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
		COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
		COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
		COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
		COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
		COMMAND_ID_HANDLER(ID_VIEW_DIALOGTEST, OnTestDlg)
		COMMAND_ID_HANDLER(ID_VIEW_FOLDER_PANE, OnViewFolderPane)
		CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
		CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
	  MESSAGE_HANDLER(WM_SIZE, OnSize)
	  MESSAGE_HANDLER(WM_OUTBAR_NOTIFY, OnOutbarNotify)
		MESSAGE_HANDLER(WM_COMMAND, OnCommand)
		NOTIFY_HANDLER(IDC_OUTLOOKK_TREE, TVN_SELCHANGED, OnSelchangedTree)
	END_MSG_MAP()

	BEGIN_UPDATE_UI_MAP(CMainFrame)
		UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
		UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
	END_UPDATE_UI_MAP()

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_bFolderState = FALSE;

    // create command bar window
		HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
		// attach menu
		m_CmdBar.AttachMenu(GetMenu());
		// load command bar images
		m_CmdBar.LoadImages(IDR_MAINFRAME);
		// remove old menu
		SetMenu(NULL);

    HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);

		CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
		AddSimpleReBarBand(hWndCmdBar);
		AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
		CreateSimpleStatusBar();

    // get the frame client rect, so that we set the splitter initial size
    // and we can get the splitter bar in the centre
    RECT rect;
    GetClientRect(&rect);
    CRect rc;
    GetClientRect(&rc);
    
    //@@
    // Note The order in which you create the splitters and the views is very important
    // otherwise some views will not paint correctly.
    
    // Give me a verticle splitter
    // Very important that m_hWndClient is populated otherwise The CMainFrame parent 
    // can't resize the m_hWndClient in UpdateLayout if m_hWndClient isn't defined.
    m_hWndClient = m_splitter.Create(m_hWnd, rect,NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN);
    
		UIAddToolBar(hWndToolBar);
		UISetCheck(ID_VIEW_TOOLBAR, 1);
		UISetCheck(ID_VIEW_STATUS_BAR, 1);

	  // Lets create the Outlook bar

    // Set the styles
    DWORD dOutlookStyles = COutBarCtrl::fDragItems|COutBarCtrl::fEditGroups|COutBarCtrl::fEditItems|COutBarCtrl::fRemoveGroups|
				  COutBarCtrl::fRemoveItems|COutBarCtrl::fAddGroups|COutBarCtrl::fAnimation;

	  // The parent is the splitter window that this control is going to be set
    if (!wndBar.Create(WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), m_splitter.m_hWnd, 1234, dOutlookStyles))
    {
      DWORD word = GetLastError(); 
      return 0;
    }
	  wndBar.SetOwner(m_hWnd);


	  imaLarge.Create(IDB_IMAGELIST, 32, 0, RGB(128,128,128));
	  imaSmall.Create(IDB_SMALL_IMAGELIST, 16, 0, RGB(0,128,128));

	  wndBar.SetImageList(&imaLarge, COutBarCtrl::fLargeIcon);
	  wndBar.SetImageList(&imaSmall, COutBarCtrl::fSmallIcon);

	  wndBar.SetAnimationTickCount(20);

	  wndBar.SetAnimSelHighlight(200);

	  wndBar.AddFolder("Outlook", 0);
	  wndBar.AddFolder("Mail", 1);

	  wndBar.InsertItem(0, 0, "Outlook Today",  0, 0);
	  wndBar.InsertItem(0, 1, "Inbox",          1, 0);
	  wndBar.InsertItem(0, 2, "Calendar",       2, 0);
	  wndBar.InsertItem(0, 3, "Contacts",       3, 0);
	  wndBar.InsertItem(0, 4, "Tasks",          4, 0);
	  wndBar.InsertItem(0, 5, "Journals",       5, 0);
	  wndBar.InsertItem(0, 6, "Notes",          6, 0);
	  wndBar.InsertItem(0, 7, "Deleted Items",  7, 0);

	  wndBar.InsertItem(1, 0, "Drafts",         8, 0);
	  wndBar.InsertItem(1, 1, "Outbox",         9, 0);
	  wndBar.InsertItem(1, 2, "Sent Items",     10, 0);

	  wndBar.SetSelFolder(0);

	  // Set the outlook splitter
    m_splitter.m_bFullDrag = false; // To get the ghost bar
    m_splitter.SetSplitterExtendedStyle(SPLIT_LEFTALIGNED);


    // Create the Outlook Folder List Pane
    HWND hPaneSplitter = m_PaneSplitter.Create(m_hWndClient, rcDefault,NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN);

    // Create the Caption Bar and set its parent as the Pane Splitter
    m_captionBar.Create(m_PaneSplitter, rcDefault,
	    NULL, WS_CHILD | WS_VISIBLE, WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);

    
    m_VerticalSplitter.Create(hPaneSplitter, rcDefault,NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN);

    // Create the Tree View
    m_tree.Create(m_VerticalSplitter, rcDefault, NULL,WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 0, IDC_OUTLOOKK_TREE);
		m_tree.SetImageList(imaSmall, TVSIL_NORMAL);

    m_captionBar.SetTreeView(&m_tree);

    // Create the pane and assign the splitter that it exist in
    m_TreePane.Create(m_VerticalSplitter.m_hWnd);
		m_TreePane.SetTitle("Folder List");
  
    // Set the tree view in the Pane
    m_TreePane.SetClient(m_tree.m_hWnd);


    // Create the Horizontal Splitter and put into the right pane
    m_HorizontalSplitter.Create(m_VerticalSplitter, rcDefault,NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN);
    m_HorizontalSplitter.m_bFullDrag = false; // To get the ghost bar

    int viewStyleEx = WS_EX_CLIENTEDGE;

    // Dummy Views
    m_view1.Create(m_HorizontalSplitter, rcDefault,_T("View1"), WS_CHILD | WS_VISIBLE, viewStyleEx );
    m_view2.Create(m_HorizontalSplitter, rcDefault,_T("View2"), WS_CHILD | WS_VISIBLE, viewStyleEx );
    m_view3.Create(m_HorizontalSplitter, rcDefault,_T("View3"), WS_CHILD | WS_VISIBLE, viewStyleEx );

    // On the left add the outlook bar, On the right its the Pane Splitter
    m_splitter.SetSplitterPanes(wndBar, hPaneSplitter);
    m_splitter.SetSplitterPos(112);

    m_PaneSplitter.SetSplitterPanes(m_captionBar, m_VerticalSplitter);
		m_PaneSplitter.SetSplitterExtendedStyle(SPLIT_NONINTERACTIVE);
    m_PaneSplitter.SetSplitterPos(33);

    m_captionBar.SetOwner(m_hWnd);

    m_VerticalSplitter.SetSplitterExtendedStyle(SPLIT_LEFTALIGNED);
    m_VerticalSplitter.SetSplitterPanes(m_TreePane, m_HorizontalSplitter);
    m_VerticalSplitter.SetSplitterPos(140);
		m_VerticalSplitter.SetSinglePaneMode(SPLIT_PANE_RIGHT);
    m_VerticalSplitter.m_bFullDrag = false; // To get the ghost bar

    m_tree.ShowWindow(SW_HIDE);
      
    m_HorizontalSplitter.SetSplitterPanes(m_view1,m_view2);
    CRect rectClient;
    m_HorizontalSplitter.GetClientRect(&rectClient);
    m_HorizontalSplitter.SetSplitterPos(rectClient.Height() /2);

    // register object for message filtering and idle updates
		CMessageLoop* pLoop = _Module.GetMessageLoop();
		ATLASSERT(pLoop != NULL);
		pLoop->AddMessageFilter(this);
		pLoop->AddIdleHandler(this);

    m_captionBar.GetCaptionBar()->SetIcon(imaSmall.ExtractIcon(0));
    UpdateTreeList();

		return 0;
	}

	void AddTreeRootLevel()
	{
		// Connections
		TVINSERTSTRUCT tvInsert;
		tvInsert.hParent = NULL;
		tvInsert.hInsertAfter = NULL;
		tvInsert.item.mask = TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE;
		tvInsert.item.pszText = _T("Outlook Today");
		tvInsert.itemex.iImage	= 0;
		tvInsert.itemex.iSelectedImage	= 0;
		
		m_hConnections = m_tree.InsertItem(&tvInsert);
	}

	void UpdateTreeList()
	{
		// delete all items
		m_tree.DeleteAllItems();

		AddTreeRootLevel();

		// Add it to the tree
		HTREEITEM hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Inbox"), 1, 1, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Calendar"), 2, 2, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Contacts"), 3, 3, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Tasks"), 4, 4, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Journals"), 5, 5, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Notes"), 6, 6, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Deleted Items"), 7, 7, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Drafts"), 8, 8, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Outbox"), 9, 9, 0, 0, 0, m_hConnections, NULL);
		hPA = m_tree.InsertItem(TVIF_IMAGE | TVIF_TEXT | TVIF_SELECTEDIMAGE,
				_T("Sent Items"), 10, 10, 0, 0, 0, m_hConnections, NULL);
    
    m_tree.Expand(m_hConnections, TVE_EXPAND);
	}

  LRESULT OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		PostMessage(WM_CLOSE);
		return 0;
	}

	LRESULT OnFileNew(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		// TODO: add code to initialize document

		return 0;
	}

	LRESULT OnViewToolBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		static BOOL bVisible = TRUE;	// initially visible
		bVisible = !bVisible;
		CReBarCtrl rebar = m_hWndToolBar;
		int nBandIndex = rebar.IdToIndex(ATL_IDW_BAND_FIRST + 1);	// toolbar is 2nd added band
		rebar.ShowBand(nBandIndex, bVisible);
		UISetCheck(ID_VIEW_TOOLBAR, bVisible);
		UpdateLayout();
		return 0;
	}

	LRESULT OnViewStatusBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		BOOL bVisible = !::IsWindowVisible(m_hWndStatusBar);
		::ShowWindow(m_hWndStatusBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
		UISetCheck(ID_VIEW_STATUS_BAR, bVisible);
		UpdateLayout();
		return 0;
	}

	LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		CAboutDlg dlg;
		dlg.DoModal();
		return 0;
	}
	LRESULT OnTestDlg(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		return 0;
	}
  
	LRESULT OnViewFolderPane(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
	{
		m_bFolderState = !m_bFolderState;
		if (m_bFolderState)
		{
			m_VerticalSplitter.SetSinglePaneMode(SPLIT_PANE_NONE);
			m_VerticalSplitter.SetSplitterPos(140);
      m_tree.ShowWindow(SW_SHOW);
      m_TreePane.UpdateLayout();
      
      // Make the button dis-appear
      m_captionBar.GetCaptionBar()->ShowButton(false);
      
		}
		else
		{
			m_VerticalSplitter.SetSinglePaneMode(SPLIT_PANE_RIGHT);
      m_tree.ShowWindow(SW_HIDE);
      m_captionBar.GetCaptionBar()->ShowButton(true);
		}
		UISetCheck(ID_VIEW_FOLDER_PANE, m_bFolderState);
		UpdateLayout();
		return 0;
	}

  LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		// if command comes from the close button, substitute HWND of the pane container instead
		if(m_TreePane.m_hWnd != NULL && (HWND)lParam == m_TreePane.m_hWnd)
		{
			//m_bFolderState = TRUE;
			return SendMessage(WM_COMMAND, ID_VIEW_FOLDER_PANE);
		}

		bHandled = FALSE;
		return 1;
	}

	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
    CRect paneRect;
    int nHeight = 300;
    if (m_captionBar.m_hWnd)
    {
      m_captionBar.GetClientRect(&paneRect);
      nHeight = paneRect.bottom - paneRect.top;
    }
    if (m_VerticalSplitter.m_hWnd)
    {
      // Add a bit for the horizontal border
      nHeight += 10;
      m_VerticalSplitter.GetClientRect(&paneRect);
      nHeight += paneRect.bottom - paneRect.top;        
    }
    m_captionBar.SetPaneHeight(nHeight);

    return 0;
  }


	LRESULT OnSelchangedTree(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
	{
	  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pnmh;

    int nImageIndex;
	  HTREEITEM htreeItem = m_tree.GetSelectedItem();
	  m_tree.GetItemImage( htreeItem, nImageIndex, nImageIndex );
    
    CString sText;
    m_tree.GetItemText( htreeItem, sText);
    m_captionBar.GetCaptionBar()->SetCaptionText(sText);
    m_captionBar.GetCaptionBar()->SetIcon(imaSmall.ExtractIcon(nImageIndex));

		return 0;
	}

  LRESULT OnOutbarNotify(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
  {
	  switch (wParam)
	  {
		  case NM_OB_ITEMCLICK:
		  // cast the lParam to an integer to get the clicked item
			  {
				  int index = (int) lParam;
				  CString cs(wndBar.GetItemText(index));
          //m_captionBar.GetCaptionBar()->SetCaptionText(cs);

          // need to change the icon on the Captionbar
          //m_captionBar.GetCaptionBar()->SetIcon(imaSmall.ExtractIcon(m_nIconStartIndex + index));

				  //MessageBox(cs, "Outlook Bar", MB_OK);
			    int nFolder = wndBar.GetSelectedFolder();
			
			    HTREEITEM hItem = NULL;
          // get the root item
          hItem = m_tree.GetRootItem();
          // now loop round until we get the correct item
          for (int i = 0; i < m_nIconStartIndex + index; i++)
          {
            hItem = m_tree.GetNextVisibleItem(hItem);
          }

			    if(hItem) 
				    m_tree.SelectItem(hItem);

			  }
		  return 0;
		  // cast the lParam to an integer to get the selected folder
      case NM_FOLDERCHANGE:
        {
				  int nSelectedFolder = (int) lParam;
          switch(nSelectedFolder)
          {
          case 0 :
            m_nIconStartIndex = 0;
            break;
          case 1 :
            m_nIconStartIndex = 8;
            break;
          default :
            m_nIconStartIndex = 0;
          }
        
        }
      return 0;

		  case NM_OB_ONLABELENDEDIT:
		  // cast the lParam to an OUTBAR_INFO * struct; it will contain info about the edited item
		  // return 1 to do the change and 0 to cancel it
			  {
				  OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
				  //TRACE2("Editing item %d, new text:%s\n", pOI->index, pOI->cText);
			  }
		  return 1;

		  case NM_OB_ONGROUPENDEDIT:
		  // cast the lParam to an OUTBAR_INFO * struct; it will contain info about the edited folder
		  // return 1 to do the change and 0 to cancel it
			  {
				  OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
				  //TRACE2("Editing folder %d, new text:%s\n", pOI->index, pOI->cText);
			  }
		  return 1;

		  case NM_OB_DRAGITEM:
		  // cast the lParam to an OUTBAR_INFO * struct; it will contain info about the dragged items
		  // return 1 to do the change and 0 to cancel it
			  {
				  OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
				  //TRACE2("Drag item %d at position %d\n", pOI->iDragFrom, pOI->iDragTo);
			  }
		  return 1;
	  }
	  return 0;
  }

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINFRM_H__5F15259F_10A4_11D5_A093_CB9BFECE0F30__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
Was made redundant in early 2003 after 10 years in computer programming, since then started my own business (selling computer books on the net)
www.pricecutbook.co.uk


Comments and Discussions