question

RameshDeekonda-5542 avatar image
0 Votes"
RameshDeekonda-5542 asked RameshDeekonda-5542 edited

How to change the bitmaps of an Outlookbar style property sheet (class CMFCPropertySheet )

Hi,
I have created a property sheet derived from CMFCPropertySheet with three pages. I am using the property sheet in Outlookbar style.
I use the SetLook member function to set the CMFCPropertySheet::PropSheetLook_Outlookbar style. I am able to assign the Bitmaps once befor the call to DoModal().I would like to change the bitmaps on the buttons of this propertysheet after it has been created.
Once bitmaps have been et I am not able to change the bitmaps later. I would like one bitmap displayed in the selected state and another when it is unselected. Please give your suggestions on how I can do this.
I have created a function to change the image list that is used by the property sheet which is as below. This function is called from the OnSetActive function of the property pages of the property sheet.

 void AppPropSheet::ChangeImgList(int sel)
 {
 //m_bmpimgs[3] and m_bmpmask are member variables of the AppPropSheet class
        
     static bool firsttime = true;
    
     int retval;
    
     if (!firsttime)
         for (int i = 0; i < 3; i++)
         {
         m_bmpimgs[i].~CBitmap();
         }
    
    
     if (sel == 0)
         m_bmpimgs[0].LoadBitmapA(IDB_BITMAP87);
     else
         m_bmpimgs[0].LoadBitmapA(IDB_BITMAP77);
    
     if (sel == 1)
         m_bmpimgs[1].LoadBitmapA(IDB_BITMAP86);
     else
         m_bmpimgs[1].LoadBitmapA(IDB_BITMAP81);
    
     if (sel == 2)
         m_bmpimgs[2].LoadBitmapA(IDB_BITMAP88);
     else
         m_bmpimgs[2].LoadBitmapA(IDB_BITMAP79);
        
     if(firsttime)
     m_bmpmask.LoadBitmapA(IDB_BITMAP80);
    
        
     if (!firsttime)
     {
         m_shtSelImages.Remove(2);
         m_shtSelImages.Remove(1);
         m_shtSelImages.Remove(0);
         ImageList_Destroy(m_shtSelImages.m_hImageList);
         retval = m_shtSelImages.Create(81, 81, ILC_COLOR24 | ILC_MASK, 1, 1);
            
         retval=m_shtSelImages.Add(&bmpimgs[0],RGB(128,128,128));
         retval=m_shtSelImages.Add(&bmpimgs[1], RGB(128, 128, 128));
         retval=m_shtSelImages.Add(&bmpimgs[2], RGB(255, 255, 255));
        
         //SetIconsList(m_shtSelImages.m_hImageList);//commented because it asserts here
         RedrawWindow();
     }
     firsttime = false;
        
 }
c++windows-api
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RameshDeekonda-5542 avatar image
0 Votes"
RameshDeekonda-5542 answered RameshDeekonda-5542 edited

@Castorix31, I am obliged for his work on my question.The bitmaps that are used should all be of same size I think otherwise the output is getting mixed up. This is the working code for achieving the changed buttons.However the change of images is no so smooth.

 void  ChangeImageList(int sel)
 {
          for (int i = 0; i < 3; i++)
               {
               m_bmpimgs[i].~CBitmap();
               }
           if (sel == 0)
                 retval=m_bmpimgs[0].LoadBitmapA(IDB_BITMAP87);
           else
                 retval=m_bmpimgs[0].LoadBitmapA(IDB_BITMAP77);
                    
           if (sel == 1)
                 retval=m_bmpimgs[1].LoadBitmapA(IDB_BITMAP86);
           else
                 retval=m_bmpimgs[1].LoadBitmapA(IDB_BITMAP81);
                    
           if (sel == 2)
                 retval=m_bmpimgs[2].LoadBitmapA(IDB_BITMAP88);
           else
                 retval=m_bmpimgs[2].LoadBitmapA(IDB_BITMAP79);
                          
           m_wndPane1.RemoveAllButtons();
        
           //This line not to be used
           //m_wndPane1.ClearAll();
                    
           retval=m_wndPane1.AddButton(m_bmpimgs[0], "Button one text", 10050, 0);
           retval=m_wndPane1.AddButton(m_bmpimgs[1], "Button Two Text", 10051, 1);
           retval=m_wndPane1.AddButton(m_bmpimgs[2], "Button three text", 10052, 2);
                                 
           m_wndPane1.InvalidateButton(0);
           m_wndPane1.InvalidateButton(1);
           m_wndPane1.InvalidateButton(2);
                    
 }






· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

The loading of bitmaps each time is obviously taking up some time. I am looking into that.

0 Votes 0 ·
XiaopoYang-MSFT avatar image
0 Votes"
XiaopoYang-MSFT answered RameshDeekonda-5542 commented

Generally, after getting the handle to the buttons, you can change their bitmap anytime. Searching Hacking the CPropertySheet for more details.

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

The framework seems to use its own copy of the bitmaps which are stored internally and not accessible.Any painting which I do gets painted over by the framework. On which object and which event should I handle the painting?.

0 Votes 0 ·

The framework is overpainting whatever I paint using Bitblt in the PropertySheet::OnPaint I have tried several options like painting in OnNCpaint of property sheet. Subclassing the m_wndOutloookBar member of the property sheet etc. but it doesn't change the bitmaps.
Which is the underlying window object corresponding to the panes of the outlookbar?.

0 Votes 0 ·
RameshDeekonda-5542 avatar image
0 Votes"
RameshDeekonda-5542 answered RameshDeekonda-5542 edited

The framework seems to use its own copy of the bitmaps which are stored internally and not accessible.In which event can I do my own painting in the tab area which will not be over painted later by the framework.

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If you're talking about Toolbar buttons in the CMFCOutlookBar of the CMFCPropertySheet, you can subclass it and draw over in WM_PAINT, but it is not a great solution

A test with the MS sample "NewControls" where I draw a red ellipse over the first button :


143060-cmfcpropertysheet.gif


1 Vote 1 ·
cmfcpropertysheet.gif (270.7 KiB)

Can you post the code which yous used to subclass. I am confused with tabs and panes. for .e.g if there are three tabs in my property sheet then do i have thee panes also?.Do I have to subclass each of the three tab windows separately, or can I do with
subclassing the parent window.

I experimented with other members of the propertysheet such as m_wndPane1 and m_wndTab. I accessed m_wndPane1.GetImages() using CMFCToolBarImages* imgs = m_wndPane1.GetImages();

then I used imgs.CleanUp() this cleared the images but new images did not display on adding new images to imgs.

0 Votes 0 ·
Castorix31 avatar image Castorix31 RameshDeekonda-5542 ·

In fact, you can access Toolbar buttons from m_wndPane1

In this test, I removed the 3rd button and changed the image of the 2nd button with the 4th image :
(*((CMFCToolBar*)&(*((CMFCOutlookBarPane*)&m_wndPane1)))).RemoveButton(2);
CMFCToolBarButton* pButton = (*((CMFCToolBar*)&(*((CMFCOutlookBarPane*)&m_wndPane1)))).GetButton(1);
pButton->SetImage(3);

143145-cmfcpropertysheet.jpg



0 Votes 0 ·
cmfcpropertysheet.jpg (104.1 KiB)