Click here to Skip to main content
Click here to Skip to main content

Outlook Bar Control and Frame (WTL)

By , 27 Jun 2001
 

Sample Image - atloutlookbar3.gif

Credit and Acknowledgments

First of all I would like to credit the Original Author Iuri Apollonio on the fantastic control that he has developed using MFC. His code has been used to port the control to WTL with a few WTL tweaks and fixes. The original article can be found at

The Outlook caption bar is based on the Window Caption Bar written by Maxime Labelle, the original article can be found at http://www.codeproject.com/useritems/captionbarctrl.asp

The Flatbutton on the caption bar is based on Davide Calabro's excellent CButtonST class, that has been ported to WTL. The Flatbutton class has been extended to include functionality to get the outlook flatbutton style.

Overview

I needed a Outlook bar to use in a ATL/WTL project, my attention turned to Iuri Apollonio Outlook bar Control that was MFC based and this article basically ports the original CGfxOutBarCtrl. Three ATL files contain the port.
  • atloutbarctrl.h (Contains the main COutBarCtrl Class for WTL)
  • atlgroupedit.h (Contains the CGroupEdit class for WTL and used by the COutBarCtrl Class)
  • atloutbarsplit.h (Contains the COutlookSplitterWindow class for WTL and used by the COutBarCtrl Class)

The caption bar can be found in

  • atlcaptionbar.h (Contains the main CCaptionBar)

The flatbutton class can be found in

  • atlflatbutton.h (Contains the main CButtonST class)

The COutlookSplitterWindow bar is inherited from the WTL CSplitterWindow class, additional functionality had to be added to make the left pane aligned (i.e. left pane does not move width wise when the app is resized). This functionality strangely exist in the base class for a right pane. Further tweks had to be added to make it act like a outlook splitter. The original CGfxSplitterWindow has not been ported as MFC and WTL splitter classes vary.

Requirements

You will require the WTL Libraries, these can be downloaded from the microsoft site, there are various articles on the net that tell you how to do this, so I won't bore you with the details.

Note - This control uses the WTL CString class and the STL std::list template class.

How to use the control in your WTL App

  1. Make sure you have the following ATL files included in your stdafx.h

    • atlwin.h
    • atlctrls.h
    • atlmisc.h

    atlmisc.h is required as it has the definition for the WTL CString Class

  2. Add the header file atloutbarctrl.h and atloutbarsplit.h to the Main frame class and declare an instance of the Outlook bar control, Outlook Bar Splitter objects and the Image Lists that are to be used in the outlook bar.
    COutBarCtrl wndBar;
    CImageList imaLarge, imaSmall;
    COutlookSplitterWindow m_splitter
    
  3. Create the outlook splitter class e.g.
    m_hWndClient = m_splitter.Create(m_hWnd, rect, NULL, 
        WS_CHILD | WS_VISIBLE);
  4. Create the outlook bar control and set the image lists on the OnCreate function in the Main Frame class e.g.
    DWORD dwf = COutBarCtrl::fDragItems|COutBarCtrl::fEditGroups|
        COutBarCtrl::fEditItems|COutBarCtrl::fRemoveGroups| 
    COutBarCtrl::fRemoveItems|COutBarCtrl::fAddGroups|
        COutBarCtrl::fAnimation; 
    if (!wndBar.Create(WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), 
        m_splitter.m_hWnd, 1234, dwf)) 
    { 
       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("Folder 1", 0);
    wndBar.AddFolder("Folder 2", 1);
    wndBar.AddFolder("Folder 3", 2);
    
    wndBar.InsertItem(0, 0, "Item 1", 0, 0);
    wndBar.InsertItem(0, 1, "Item 2", 1, 0);
    wndBar.InsertItem(0, 2, "Item 3", 2, 0);
  5. You need to set a few of the splitter methods for it to act like a outlook splitter.
    m_splitter.m_bFullDrag = false; // Draws the Ghost bar instead
    m_splitter.SetSplitterExtendedStyle(SPLIT_LEFTALIGNED); 
      // Aligns the outlook bar to the left
    
    m_splitter.SetSplitterPanes(wndBar, m_list); 
      // Set the outlook bar on the left pane
    
    m_splitter.SetSplitterPos(120); // width of the initial outlook bar
  6. To receive Events on when the tab has been selected add the Macro to the message Map.
    MESSAGE_HANDLER(WM_OUTBAR_NOTIFY, OnOutbarNotify)

    On the onNotify handler, trap the Events.

    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, cs1;
         cs1 = wndBar.GetItemText(index);
         cs.Format("Clicked on %d - <%s>", (int)lParam, cs1);
         MessageBox(cs, "Outlook Bar", MB_OK);
        }
        return 0;
    
        case NM_OB_ONLABELENDEDIT:
        // cast the lParam to an OUTBAR_INFO * struct; 
        // it will contain info about the edited item
        {
           OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
        }
        return 1;
    
        case NM_OB_ONGROUPENDEDIT:
        // cast the lParam to an OUTBAR_INFO * struct; 
        // it will contain info about the edited folder
              {
           OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
        }
        return 1;
    
        case NM_OB_DRAGITEM:
        // cast the lParam to an OUTBAR_INFO * struct; 
        // it will contain info about the dragged items
              {
           OUTBAR_INFO * pOI = (OUTBAR_INFO *) lParam;
        }
        return 1;
       }
       return 0;
    }

The Demo App shows how to use the control in full.

Updates

  • v1.00 - Initial Port
  • v1.01 - Added Outlook Caption Bar to demo app also shows how to use nested vertical and horizontal splitter bar to get outlook feel. Fixed potential painting problem in outlook control when resizing the application.
  • v1.02 - Extended the Outlook framework, by adding the flat button on the caption bar. Also uses panes to lock and unlock the floating tree window.

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

About the Author

Rashid Thadha
Web Developer
United Kingdom United Kingdom
Member
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
 

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralTooltips for the itemsmemberdaphna2 Feb '05 - 18:15 
I have tried to add tooltip for each item but from some reason didn't get to the TTN_NEEDTEXT message.
Do you have any Idea how can I implement tooltips?
Questionhow to add outlook bar to a MDI project?sussAnonymous25 Nov '03 - 14:15 
Hi, I want to add this control to Mainframe of a MDI project,as you know,We couldn't cite OncreateClients in Mainframe,what I can do? thanks!
Questioncompilation Error?sussMurali.M7 Oct '03 - 22:29 
hi,
 
i got the compilation error. imagelist_read and imagelist_write undeclared identifier. CString, CDC and some class are ambigious symbols. what can i do for that. pls explain to me. i have wtl 7.0. any other files need for that.
 
thanks in advance.
GeneralMessage Loopmemberdonno2020 Aug '03 - 23:27 
Why there is message loop in OnLButtonDown function ?
GeneralRe: Message LoopmemberCui Sheng8 Mar '04 - 14:09 
Hi,donno20,
 
Have you solved it?
Best regards,
 
Smile | :)
 

 
Cui Sheng
shengcui@hotmail.com

Generaladvanced usagememberModar4 May '03 - 7:46 
Hi thanks for this article,but i'm wandring if we can implement it in a dialog
that would be perfect anyone have an ideaSmile | :)
QuestionGDI Problems after 800-1000 WM_PAINT messages?memberIsmail Ufuk PAZARBASI30 Mar '03 - 10:54 
Hi,
 
nice project. I have added some gradient painting code to caption bar, and I have added redraw code in idle handler, and also sent some painting messages from different threads with redrawwindow function with RDW_INTERNALPAINT parameter. Anyway, after few minutes, or I think about 800-1000 WM_PAINT messages, things start going bad. WM_PAINT handler caused some GDI problems, and other windows of the application are not painted correctly, such as about dialog. Static control's fonts alike System font, buttons are not drawn... May be I have done something GDI does not like, or your code may have problem. I am not good at forensics of WM_PAINT troubles, and I thought it would be better to examine your code together to figure out what's going on, because your code still exists in my project but only background filling stuff changed. I am posting my code, I would be grateful, if you add this code to your one, and test it. I have changed caption text as well. Caption is dynamic, and collecting caption text from an array in memory, increases a number by 1, and redraws the caption. After 1sec, caption is receiving another WM_PAINT message, and increases number by 1 again, and so on...
 
I have removed CDC allocation from heap, and put it on stack. This should increase speed. Here my code goes:
 
CRect rect, rectOriginal;
GetClientRect(&rect);
rectOriginal = rect;

// double buffering for smoother flicker free drawing
CDC pDC; // Ismail: removed allocation from heap. I think this should be faster

pDC.CreateCompatibleDC(hDC.m_hDC);
CBitmap bmp;
bmp.CreateCompatibleBitmap(hDC.m_hDC, rect.Width(), rect.Height());
HBITMAP obmp = pDC.SelectBitmap(bmp);

if (m_bFlatEdge)
pDC.DrawEdge(&rect, EDGE_ETCHED, BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM | BF_ADJUST);
rect.DeflateRect(m_nBorder, m_nBorder);

// Draw the background
// Ismail: I have added following gradient filling code
pDC.SetBkMode(TRANSPARENT);

TRIVERTEX tx[2];
tx[0].x=0;
tx[0].y=0;
tx[0].Red=0x6900;
tx[0].Green=0xb700;
tx[0].Blue=0xff00;
tx[0].Alpha=0x0000;

tx[1].x=rect.Width()+5;
tx[1].y=1;
tx[1].Red=0x6800;
tx[1].Green=0x7b00;
tx[1].Blue=0xbd00;
tx[1].Alpha=0x0000;

TRIVERTEX tx2[2];
tx2[0].x=0;
tx2[0].y=1;
tx2[0].Red=0x3900;
tx2[0].Green=0x9800;
tx2[0].Blue=0xE800;
tx2[0].Alpha=0x0000;

tx2[1].x=rect.Width()+5;
tx2[1].y=rect.Height();
tx2[1].Red=0x1800;
tx2[1].Green=0x7200;
tx2[1].Blue=0xbe00;
tx2[1].Alpha=0x0000;

TRIVERTEX tx3[2];
tx3[0].x=0;
tx3[0].y=rect.Height()-1;
tx3[0].Red=0x1f00;
tx3[0].Green=0x7200;
tx3[0].Blue=0xb900;
tx3[0].Alpha=0x0000;

tx3[1].x=rect.Width()+5;
tx3[1].y=rect.Height();
tx3[1].Red=0x6600;
tx3[1].Green=0x3300;
tx3[1].Blue=0x9900;
tx3[1].Alpha=0x0000;

GRADIENT_RECT gRect;

gRect.UpperLeft=0;
gRect.LowerRight=1;
GradientFill(pDC.m_hDC,tx,2,&gRect, 1, GRADIENT_FILL_RECT_H);
GradientFill(pDC.m_hDC,tx2,2,&gRect, 1, GRADIENT_FILL_RECT_H);
GradientFill(pDC.m_hDC,tx3,2,&gRect, 1, GRADIENT_FILL_RECT_H);
// rest is almost same, I have changed ExtTextOut to DrawText

 

Thanks!
AnswerRe: GDI Problems after 800-1000 WM_PAINT messages?memberSteve Mayfield30 Mar '03 - 12:22 
Although I have not looked at this code, I had a similar problem with one of my applications a few months ago. I tracked it down to not calling SelectObject() to restore original values after changing them (pens, fonts, foreground/background color, bitmaps...etc) in the onDraw/OnPaint procedures.
 
Steve
GeneralC# Versionmembermokah19 Mar '03 - 6:56 
Thanks for the control.How can I use it in C# or vb.net.
If possible, I would'nt mind a vb version of it.

 
Mokah
GeneralSmall icons, long labelsmemberPaul S. Vickery17 Feb '03 - 4:18 
Great control, but there is something I wish it had.
 
If I am viewing in small icon view, and have quite long labels, I can't read the label text. What I feel the control needs is to show a tool-tip when hovering over an item whose label is obscured, like you get in the standard Windows tree control.
 
Does anyone have any code to do this? I've tried using tool-tips but find it very difficult to get them to do what I want.
 
Paul.

 
---
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
GeneralIcon background color problem.memberIlushka13 Nov '02 - 22:21 
I found out that when icons of bar items in bar folders are drawn, they do not use background color as it was intended. The back ground color is hardcoded (hardpainted, ehh.. Smile | :) ) into the bitmaps that represent those two imagelists.
 
When i wanted to use some transparensy, just got screwed up. Frown | :(
 
what did i do:
 
1. Created two icons, using background color. For ex. IDI_ICON1, and IDI_ICON2.
2. Added them to image lists in CBarFolder, using AddIcon, at the initialization time.
3. Set background color to CLR_NONE using SetBkColor
 
ima->SetBkColor(CLR_NONE);
 
4. Painted it.
 
ima->Draw(pDC->m_hDC, pi->iImageIndex, pt, ILD_NORMAL);
 

And that does nothing Frown | :(
Whats wrong with the code?
 
1. Should i use overlay images when using .Draw?
2. Did i do wrong when creating icons in resource editor?
3. Image lists were created actually far from the module in dlls, 1 dll for each folder. Is that it?
4. ...?
 
Dead | X| Mad | :mad:
 

 
Sincerely yours, Ilya Kalujny.
QuestionAre 256 color icons possible?memberclintsinger7 Aug '02 - 12:52 
It seems that only 16 color icons work in the Outlook Bar control. Is there anyway to use 256 or true color icons instead?
 
Thanks,
Clint
Generalmap the messagesussAnonymous30 Jul '02 - 20:35 
How can I map the message,when clicking the the treeitems,then set the right view's content?
best regards.
roobee@yeah.net
GeneralAddding Button to Standard OutLook Toolbarmemberajith7 Apr '02 - 20:59 
Hi,
I want to add a button to standard outlook toolbar. If you know how to do this, please let me know.
Regards,
Ajith.Smile | :)
 
AjithBuwa.
GeneralReceiving and Sending email or Creating/Viewing tasksmemberAnonymous8 Nov '01 - 8:56 
If I want to use this ATL/WTL application OutLook control in my application for sending and receiving email;what Should I do? Are there any API to Microsoft Outlook application to pull out my email messages?.
 
I have similar question about Task?
Could I get some ideas from you all how you have used this control?
Thanks
Pati
 
nrc
GeneralAnotjher minor drawing detailmemberAnonymous3 Jul '01 - 2:28 
If you add DT_END_ELLIPSIS to the DrawText-calls in the DrawFolder method, it's event closer to the original
 
Again just a suggestin Big Grin | :-D
 
Pål
GeneralRe: Anotjher minor drawing detailmemberRashid Thadha3 Jul '01 - 11:54 
Thanks again
 
I have updated the code, for the next releaseSmile | :)
GeneralMinor drawing detailmemberAnonymous3 Jul '01 - 2:20 
To make the outlookbar look even more like the original, the following change can be done to the OnPaint-method in atloutbarctrl.h:
 
change from
 
if (!GetFolderChild())
pDC->FillSolidRect(rc, crBackGroundColor);
 
to
 
if (!GetFolderChild()) {
pDC->FillSolidRect(rc, crBackGroundColor);
// adds a dark shadow at edge
pDC->Draw3dRect(rc, crDkShadowBorder, crBackGroundColor);
}
 
Just a suggestion Smile | :)
 
Thanks for a nice article
GeneralRe: Minor drawing detailmemberRashid Thadha3 Jul '01 - 11:54 
Thanks
 
I have updated the code, for the next releaseSmile | :)
Generalcompiled errormemberAnonymous26 Jun '01 - 20:41 
How can i find " atlres.h " ?
GeneralRe: compiled errormemberRashid Thadha27 Jun '01 - 3:18 
You need the WTL Library
 
see the article http://www.codeproject.com/wtl/wtlinst.asp on how to download the latest version of WTL.
 
Smile | :)
Generalwont compile.memberAnonymous8 May '01 - 13:37 
I get error when trying to compile. Basically DrawIconEx is not a member of CDT<1>. any ideas? My second question... have you made this into an axtive X control that I might be able to put into a ATL DHTML Control to display in an app?
 
Thanks....
 

Derek
GeneralRe: wont compile.memberRashid Thadha8 May '01 - 22:55 
check the version of your WTL Library. It should be v3.1
 
see the article http://www.codeproject.com/wtl/wtlinst.asp on how to download the latest version of WTL.
 
also I have not made this into an ActiveX control
Generala bug...memberdevhead015 May '01 - 9:55 
i have try out your outlookbar... emm.. but after i remove the last item "folder" the sample program crash... gee i should allow user to remove my bar at all i guess...;)
 
knowledge is power
GeneralRe: a bug...memberDerek Strasen10 May '01 - 6:29 
The control is getting a msg from WM_PAINT. If there are no folders in the control to paint it will crash due to calls to GetBarFolderListItem that might return a NULL pointer and accesses them directly after without checking first. In debug builds this should assert as the author does a check for (iFolder < GetFolderCount()) Although does not return an error if this happens. So in release builds and there are no items it will crash.
 
This is very easily fixed by adding a return using similar logic as the assert in the paint functions and a few others.
 
I also added the following lines to OnPaint during my own developments while making this an ActiveX control..
 
//Ths is the ORIGINAL code from the author to show the insertion point.
GetInsideRect(rc);
if (!GetFolderChild())
pDC->FillSolidRect(rc, crBackGroundColor);
int max = arFolder.size();
 
//The following is added code........
if (max == 0)
{
dc.BitBlt(clientRc.left, clientRc.top, clientRc.Width(), clientRc.Height(), pDC->m_hDC, 0,0, SRCCOPY);
if (pDC)
delete pDC;
return 0;
}

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 28 Jun 2001
Article Copyright 2001 by Rashid Thadha
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid