Click here to Skip to main content
Email Password   helpLost your password?

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.

The caption bar can be found in

The flatbutton class can be found in

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

    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

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralTooltips for the items
daphna
19:15 2 Feb '05  
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?
Generalhow to add outlook bar to a MDI project?
Anonymous
15:15 25 Nov '03  
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!
Generalcompilation Error?
Murali.M
23:29 7 Oct '03  
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 Loop
donno20
0:27 21 Aug '03  
Why there is message loop in OnLButtonDown function ?
GeneralRe: Message Loop
Cui Sheng
15:09 8 Mar '04  
Hi,donno20,

Have you solved it?
Best regards,

Smile



Cui Sheng
shengcui@hotmail.com

Generaladvanced usage
Modar
8:46 4 May '03  
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
GeneralGDI Problems after 800-1000 WM_PAINT messages?
Ismail Ufuk PAZARBASI
11:54 30 Mar '03  
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!
GeneralRe: GDI Problems after 800-1000 WM_PAINT messages?
Steve Mayfield
13:22 30 Mar '03  
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# Version
mokah
7:56 19 Mar '03  
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 labels
Paul S. Vickery
5:18 17 Feb '03  
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.
Ilushka
23:21 13 Nov '02  
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 nothingFrown
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 Mad



Sincerely yours, Ilya Kalujny.
GeneralAre 256 color icons possible?
clintsinger
13:52 7 Aug '02  
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 message
Anonymous
21:35 30 Jul '02  
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 Toolbar
ajith
21:59 7 Apr '02  
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 tasks
Anonymous
9:56 8 Nov '01  
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 detail
Anonymous
3:28 3 Jul '01  
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

Pål
GeneralRe: Anotjher minor drawing detail
Rashid Thadha
12:54 3 Jul '01  
Thanks again

I have updated the code, for the next releaseSmile
GeneralMinor drawing detail
Anonymous
3:20 3 Jul '01  
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 detail
Rashid Thadha
12:54 3 Jul '01  
Thanks

I have updated the code, for the next releaseSmile
Generalcompiled error
Anonymous
21:41 26 Jun '01  
How can i find " atlres.h " ?
GeneralRe: compiled error
Rashid Thadha
4:18 27 Jun '01  
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.
Anonymous
14:37 8 May '01  
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.
Rashid Thadha
23:55 8 May '01  
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...
devhead01
10:55 5 May '01  
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...
Derek Strasen
7:29 10 May '01  
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;
}


Last Updated 28 Jun 2001 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010