Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » CDRControlBar - Blink Title Bar Collapse All
Subject Author Date
Adam Keadey Aug 31, 2007 - 12:22 PM

I want to blink the title bar by swapping the text color and background color using a timer.

What can I override to do this?

Technical Support Sep 21, 2007 - 5:29 AM

We think handling clicks on the caption of a control bar (a floating mini frame) is not a good idea in this context because the control bar’s child window gets focused in this case and the control bar’s window become active as a result. Instead, you could analyze if the control bar’s active state has changed. If it works for you, you can override the CExtControlBar::OnUpdateCmdUI() virtual method, invoke the parent class’s method and check what is the flag value returned by CExtControlBar::IsBarWindowActive().

Adam Keadey Sep 20, 2007 - 11:00 AM

I would really prefer to have it blink forever if there is a way to reserve a number like -2 or use 0 like I previously suggested to flash forever.

Technical Support Sep 20, 2007 - 10:36 AM

You can stop flashing by using pBar->FlashCaption(); without parameters. The zero value should not be used in nFlashCaption parameter. The "forever" flashing is implemented as 65635 value in nFlashCaption (you can also specify 1000000 in it). That is not forever actually but quite close to forever. To test the flashing feature, you can put the following lines at the end of the CMainFrame::OnCreate() method of the SDIDOCVIEW sample:

m_wndResizableBarEdit.FlashCaption( 65535, 375 );
m_wndResizableBarCP.FlashCaption( 65535, 500, RGB(224,224,224), RGB(132,0,132) );
m_wndResizableBarTree.FlashCaption( 65535, 250, RGB(255,255,0), RGB(0,128,0) );

Technical Support Sep 18, 2007 - 11:30 AM

We are sorry for this inconvenience. We fixed this compilation problem. So, you can request the updated source by email at support@prof-uis.com.

Technical Support Aug 31, 2007 - 1:24 PM

The caption of a control bar is painted in the CExtControlBar::DoPaintNC() virtual method. so you can override it. Your DoPaintNC() method should be similar to the original one and invoked on timer. The following part of the original method paints the caption:

            CExtPaintManager::PAINTGRIPPERDATA _pgd(
                  this,
                  rcGrip,
                  rcText,
                  IsBarWindowActive(),
                  false,
                  bHorz && !bGripperAtTop,
                  !bFixedMode,
                  sCaption.IsEmpty() ? LPCTSTR( NULL ) : sCaption,
                  ( (g_ResourceManager->OnQueryLangLayout()&LAYOUT_RTL) != 0 ) ? true : false
                  );
            PmBridge_GetPM()->PaintGripper( *pDC, _pgd );
You can simply replace the IsBarWindowActive() code with true or false value depending on timer invocation and bar caption will blink.

Additionally, the tabbed bar group’s caption is part of the CExtDynTabControlBar window. So, you will also need to create your CExtDynTabControlBar-derived class which implements its own blinking caption. Here is how you can use your own tab container control bar in Prof-UIS (you should handle the CExtControlBar::g_nMsgCreateTabbedBar registered message):
afx_msg LRESULT OnMsgCreateTabbedBar( WPARAM wParam, LPARAM lParam );

ON_REGISTERED_MESSAGE( CExtControlBar::g_nMsgCreateTabbedBar, OnMsgCreateTabbedBar )
 
LRESULT CMainFrame::OnMsgCreateTabbedBar( WPARAM wParam, LPARAM lParam )
{
    lParam;
    CExtDynTabControlBar ** ppBar = (CExtDynTabControlBar **)wParam;
    (*ppBar) = new C_YOUR_DynTabControlBar;
    return 0L;
}
The CExtControlBar::_GetNearestTabbedContainer() virtual method returns NULL if the control bar is not in the tabbed group. It returns a pointer to your C_YOUR_DynTabControlBar object otherwise, So, you will be able to detect which bar should start the timer in order to produce the caption blinking effect.

Adam Keadey Sep 1, 2007 - 6:36 AM

OK that first part takes care of the all the docked control bars, but does not do anything for the floating control bars.

I looked arounbd and could seem to find anything that changes the way a floating control bar draws the title bar.

Help?

Technical Support Sep 1, 2007 - 9:39 AM

Floating control bars are actually placed inside a CExtMiniDockFrameWnd container window, which is also kind of CFrameWnd. The floating caption is part of this mini frame. The pBar->GetParentFrame() code can return a pointer to the main frame or to the floating mini frame depending on where is the control bar exactly, docked or floating. So, in the case of the mini frame, you should simply repaint its non-client area instead of control bar’s.

Adam Keadey Sep 4, 2007 - 9:51 AM

So I have the docked window repainting.

Question 1: To force the repaint I’m getting a ptr to main frame from AfxGetMainWnd() and calling RecalcLayout. Is this what I should be doning or there a better solution to repaint. I tried several other things and this seems to work, but I’m worried about calling that function for every window that I want to blink.

Question 2: In the CExtMiniDockFrameWnd I see that in the RenderNC function there is similar code to the CExtControlBar for drawing the caption. I’m assuming this is the function that I should override. How do I make the redraw happen on my new class instead of on the PROF-UIS CExtMiniDockDrameWnd? It seems that I need the original allocation of the CExtMiniDockFrameWnd to be my new class CMyMiniDockFrameWnd.

Question 3: This may be premature, but How do I force this to redraw? Will RecalcLayout work for floating windows as well? Assuming this is right call to make for forcing the repaint.

Technical Support Sep 4, 2007 - 1:09 PM

The RecalcLayout() method repositions all the bars in the frame window at once after delaying position changing queries in one or several bars. It is not good to use it here. Please use the following code:

CExtControlBar * pBarToRedrawCaption = . . .
CExtControlBar * pNearestContainer = pBarToRedrawCaption->_GetNearestTabbedContainer();
      if( pNearestContainer != NULL )
            pNearestContainer->SendMessage( WM_NCPAINT );
      else
            pBarToRedrawCaption->SendMessage( WM_NCPAINT );
CFrameWnd * pFrame = pBar->GetParentFrame();
      ASSERT_VALID( pFrame );
      if( pFrame->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) ) )
            pFrame->SendMessage( WM_NCPAINT );


Adam Keadey Sep 4, 2007 - 1:53 PM


Question 1
Is this supposed to answer my other questions as well? I’m wondering about how to blink the floating control bar? I assume I need to override the code the allocates the CExtMiniFrameWnd to insert my custom draw code, but can not figure out how to accomplish it.

Question 2

CFrameWnd * pFrame = pBar->GetParentFrame();

Is pBar here refering to the pBarToRedrawCaption ptr from the code provided?

Technical Support Sep 5, 2007 - 6:12 AM

Yes, you are right. You need to create and use a CExtMiniDockFrameWnd-derived class which implements the CExtMiniDockFrameWnd::RenderNC() virtual method which is similar to the original one but implements two variants of the caption painting. One is the default caption painting:

CExtPaintManager::PAINTGRIPPERDATA _pgd(
            this,
            rcCapt,
            rcText,
            bActive,
            true,
            false,
            bExtBar,
            sCaption.IsEmpty() ? LPCTSTR( NULL ) : sCaption,
            ( (g_ResourceManager->OnQueryLangLayout()&LAYOUT_RTL) != 0 ) ? true : false
            );
      PmBridge_GetPM()->PaintGripper( dc, _pgd );
The second one should paint the caption manually instead of invoking the code above. The rcCapt rectangle specifies the caption area which you can fill with some color/gradient and then paint the sCaption caption text into the rcText rectangle. This is only the difference between your class and CExtMiniDockFrameWnd class.

You will also need the following class to make all the bars in your main frame window using the new floating mini frame window implementation:
class FriendlyFrameWnd : public CFrameWnd
{
public:
      bool SetupNewMiniDockFrameWnd()
      {
            m_pFloatingFrameClass = RUNTIME_CLASS( CYourMiniDockFrameWnd );
            return true;
      }
};
The CYourMiniDockFrameWnd class is derived from CExtMiniDockFrameWnd. To setup the main frame window in your project using the new floating mini frame implementation, you should invoke the following code before creating any control bars:
CMainFrame * pMainFrame = . . .
      ((FriendlyFrameWnd*)pMainFrame)->SetupNewMiniDockFrameWnd();
We think you should not spend your time on this task if you provide us with all details. It is not a problem to improve the CExtMiniDockFrameWnd and CExtControlBar classes in Prof-UIS and implement some new method in the CExtControlBar class like the follows:
void FlashCaption(
      INT nFlashCount = -1, // negative value cancels current flashing
      INT nStepMilliseconds = 250,
      COLORREF clrFlashText = RGB(255,255,255),
      COLORREF clrFlashBackground = RGB(255,0,0)
      );
This will also work in case of toolbars and the menu bar. Besides, we have not discussed three additional cases:

1) If the control bar is inside a tabbed container and it is not selected or it is selected. Should the tab item flash?

2) If the control bar is auto hidden. Should the auto hide tab flash? Should the caption of the control bar window displayed from auto hide tabs with slide effect flash?

3) In the case of dynamic resizable control bars in document mode ( see the SDI_DynamicBars and MDI_DynamicBars sample applications): should their tab items flash and should the caption of MDI child frame window flash?

Adam Keadey Sep 5, 2007 - 11:24 AM

This code does not work or I’m missing something

CMainFrame * pMainFrame = . . .
((FriendlyFrameWnd*)pMainFrame)->SetupNewMiniDockFrameWnd();


Each time I create a docking window it set the m_pFloatingFrameClass back to CExtMiniDockFrameWnd.

I also discovered that if I override the following function

CExtMiniDockFrameWnd * CDRControlBar::OnCreateFloatingFrame(
    DWORD dwStyle
    )

I can simply allocate my own derived class.


So the end result is when I start my app any floating control bars will not blink. If I dock it and float it then it calls the above function and works fine.

Technical Support Sep 5, 2007 - 12:52 PM

It would be very helpful to debug your project. You can send it to support@prof-uis.com. In any case, we would prefer to implement this in Prof-UIS and provide you with the updated source code. Does it work for you? This should take a few days only. You could switch to a new version of Prof-UIS after that.

Adam Keadey Sep 5, 2007 - 1:05 PM

Sure,

Let me tell what I truely want then. Its a common feature in many applications.

I want to be able to set the control flashing (meaning I have new information in that window the needs to be recognized). Then when the user brings that window to be topmost, or activated that flashing stops.

So if the flashing functionality could include the ability to start the flash and have it end when the window is activate again it would be great.

Technical Support Sep 7, 2007 - 5:58 AM

We partially implemented the feature your requested (see it in this sample application). We will add the flashing for tabs and auto-hide tabs a bit later.

Adam Keadey Sep 7, 2007 - 8:17 AM

When will this be avaliable?

Any likely hood adding the functionality to stop the blinking when the window is clicked on?

Technical Support Sep 10, 2007 - 11:47 AM

You can download the updated source code from our ftp site (contact us via email for how to download it). We added the following methods to the CExtControlBar class:

     virtual bool FlashCaptionIsInProgress(
           bool * p_bFlashCaptionHighlightedState = NULL
           ) const;

     virtual bool FlashCaption(
           INT nFlashCount = -1, // negative value cancels current flashing
           INT nStepMilliseconds = 250,
           COLORREF clrFlashText = RGB(255,255,255),
           COLORREF clrFlashBackground = RGB(255,0,0)
           );
There is a new CExtTMDBS template class that provides MDI tab windows with ability to flash tab items corresponding to dynamic control bars in document mode (i.e. you should use the CExtTMDBS < CExtTabMdiWnd > template-based type instead of CExtTabMdiWnd). The tab items in the SDI tab page container are highlighted automatically.

Adam Keadey Sep 18, 2007 - 9:22 AM

I have downloaded release you posted and get the following compile error for the dll:

ExtPrint.cpp
..\INCLUDE\ExtTabWnd.h(2320) : error C2950: ’CExtTMDBS<CExtTabMdiWnd>’ : cannot explicitly instantiate an explicit specialization
..\INCLUDE\ExtTabWnd.h(2646) : fatal error C1903: unable to recover from previous error(s); stopping compilation
ExtTreeWnd.cpp
ExtTreeGridWnd.cpp
..\INCLUDE\ExtTabWnd.h(2320) : error C2950: ’CExtTMDBS<CExtTabMdiWnd>’ : cannot explicitly instantiate an explicit specialization
..\INCLUDE\ExtTabWnd.h(2646) : fatal error C1903: unable to recover from previous error(s); stopping compilation
ExtToolControlBar.cpp
..\INCLUDE\ExtTabWnd.h(2320) : error C2950: ’CExtTMDBS<CExtTabMdiWnd>’ : cannot explicitly instantiate an explicit specialization
..\INCLUDE\ExtTabWnd.h(2646) : fatal error C1903: unable to recover from previous error(s); stopping compilation
ExtToolBoxWnd.cpp
..\INCLUDE\ExtTabWnd.h(2320) : error C2950: ’CExtTMDBS<CExtTabMdiWnd>’ : cannot explicitly instantiate an explicit specialization
..\INCLUDE\ExtTabWnd.h(2646) : fatal error C1903: unable to recover from previous error(s); stopping compilation
ExtTaskPaneWnd.cpp
ExtTabWnd.cpp

...

It just keeps going like that.

Adam Keadey Sep 20, 2007 - 9:23 AM

Could you give me your smaple project?

In the sample you gave me the windows seemed to flash and not stop.

How do I make them flash and not stop?

ool CExtControlBar::FlashCaption(
    INT nFlashCount, // = -1 // negative value cancels current flashing
    INT nStepMilliseconds, // = 250
    COLORREF clrFlashText, // = RGB(255,255,255),
    COLORREF clrFlashBackground // = RGB(255,0,0)
    )

I have to put a number in the flash count. I would assume that a 0 would flash forever, but that is not the case.