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 » issue with the CExtToolControlBar Collapse All
Subject Author Date
Pierre MEDART Jan 28, 2008 - 11:29 AM

Hi,

our application has a docked view containing a tree control that host various objects and view to reports, a bit like in Visual Studio.

The issue we face is:

On the toolbar (a CExtToolControlBar), click on pixel left or right of a separator -> the toolbar is inactive.

The issue I clearly face here is that my view looses the focus -> the update mechanism is broken.

I try to restore it by setting the active view. The issue I now is that my toolbar is partially activated either the buttons linked to the tree or the ones linked to the view.

Any idea or suggestion ?

I’m using the 2.7.0 version of the toolkit.

Technical Support Jan 29, 2008 - 10:27 AM

We set a breakpoint to case WM_SETFOCUS in CExtControlBar::WindowProc(). So, we can catch the focus setting event on the toolbar. We run the SDI sample and set focus on the editor inside the Resizable Bar 0 bar. If the main frame window is active, then dragging start event of the toolbar will never make the toolbar focused. If the frame window is inactive and you are starting to drag-n-drop the toolbar window through its gripper or any separator, then the toolbar may become focused but this is not exactly related to the problem described in your message. Fortunately, the MthOutput sample application allowed us to reproduce this issue successfully. We found a situation when the code of the CExtControlBar class can really set focus to itself without analyzing whether the bar is a resizable panel bar or a toolbar. The problem can be solved in two steps:

1) Update the source code of the following overloaded version of the CExtControlBar::stat_QueryFocusChangingEnabled method:

bool CExtControlBar::stat_QueryFocusChangingEnabled(
      HWND hWndNotifyTarget,
      CWnd * pWndQueryOwner,
      HWND hWndNewFocusOwner
      )
{
      ASSERT( hWndNotifyTarget != NULL && ::IsWindow( hWndNotifyTarget ) );
      ASSERT_VALID( pWndQueryOwner );
      ASSERT( pWndQueryOwner->GetSafeHwnd() != NULL );
      ASSERT( hWndNewFocusOwner != NULL && ::IsWindow( hWndNewFocusOwner ) );
CExtControlBar * pBar = DYNAMIC_DOWNCAST( CExtControlBar, pWndQueryOwner );
      if(         pBar != NULL
            &&    pBar->IsFixedMode()
            )
            return false;
QueryFocusChangingEnabled_t _QFCE( pWndQueryOwner, hWndNewFocusOwner );
      ::SendMessage( hWndNotifyTarget, g_nMsgQueryFocusChangingEnabled, _QFCE, 0 );
      return _QFCE.m_bFocusChangingEnabled;
}
2) Modify the following part of the CExtControlBar::_DraggingStart() method:
. . .
            } // if( ! bEnableStartDragging )
      } // if( sizeWaitMouseMove.cx > 0 && sizeWaitMouseMove.cy > 0 )
      //ASSERT( CExtMouseCaptureSink::GetCapture() == hWndOwn );
      CExtMouseCaptureSink::SetCapture( hWndOwn );
      _SetCursor( point );
      m_bDragDetecting = false;

      ASSERT( g_DragStateOld.IsEmpty() );
      ASSERT( g_DragStateNew.IsEmpty() );
      g_DragStateOld.ExtBarSrcSet( this );
. . .


Pierre MEDART Jan 29, 2008 - 9:42 AM

the call stack is

>    FiREGrids.dll!FReportView::OnKillFocus(CWnd * pWnd=0x04b8ea68) Line 2400    C++
    mfc80d.dll!CWnd::OnWndMsg(unsigned int message=8, unsigned int wParam=1183186, long lParam=0, long * pResult=0x0012e230) Line 2079    C++
    mfc80d.dll!CWnd::WindowProc(unsigned int message=8, unsigned int wParam=1183186, long lParam=0) Line 1741 + 0x20 bytes    C++
    og801asd.dll!CGXGridView::WindowProc(unsigned int message=8, unsigned int wParam=1183186, long lParam=0) Line 333    C++
    FiREGrids.dll!GTBContentBasedView::WindowProc(unsigned int message=8, unsigned int wParam=1183186, long lParam=0) Line 347 + 0x14 bytes    C++
    mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x085f1818, HWND__ * hWnd=0x00401008, unsigned int nMsg=8, unsigned int wParam=1183186, long lParam=0) Line 240 + 0x1c bytes    C++
    mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x00401008, unsigned int nMsg=8, unsigned int wParam=1183186, long lParam=0) Line 389    C++
    mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x00401008, unsigned int nMsg=8, unsigned int wParam=1183186, long lParam=0) Line 411 + 0x15 bytes    C++
    user32.dll!GetDC() + 0x6d bytes    
    [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
    user32.dll!GetDC() + 0x14f bytes    
    user32.dll!DefWindowProcW() + 0x184 bytes    
    user32.dll!DefWindowProcW() + 0x1d0 bytes    
    ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 bytes    
    user32.dll!SetFocus() + 0xc bytes    
    ProfUIS270nd.dll!CExtControlBar::_DraggingStart(const CPoint & point={...}, const CPoint & pointOffset={...}, CSize sizeWaitMouseMove={...}) Line 12176    C++
    ProfUIS270nd.dll!CExtControlBar::OnLButtonDown(unsigned int nFlags=1, CPoint point={...}) Line 9960 + 0x2d bytes    C++
    ProfUIS270nd.dll!CExtToolControlBar::OnLButtonDown(unsigned int nFlags=1, CPoint point={...}) Line 10789    C++
    mfc80d.dll!CWnd::OnWndMsg(unsigned int message=513, unsigned int wParam=1, long lParam=655768, long * pResult=0x0012e8e8) Line 2169    C++
    mfc80d.dll!CWnd::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=655768) Line 1741 + 0x20 bytes    C++
    mfc80d.dll!CControlBar::WindowProc(unsigned int nMsg=513, unsigned int wParam=1, long lParam=655768) Line 504 + 0x14 bytes    C++
    ProfUIS270nd.dll!CExtControlBar::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=655768) Line 8536    C++
    ProfUIS270nd.dll!CExtToolControlBar::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=655768) Line 12839    C++
    mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x04b8ea68, HWND__ * hWnd=0x00120dd2, unsigned int nMsg=513, unsigned int wParam=1, long lParam=655768) Line 240 + 0x1c bytes    C++
    mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x00120dd2, unsigned int nMsg=513, unsigned int wParam=1, long lParam=655768) Line 389    C++
    mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x00120dd2, unsigned int nMsg=513, unsigned int wParam=1, long lParam=655768) Line 411 + 0x15 bytes    C++
    user32.dll!GetDC() + 0x6d bytes    
    user32.dll!GetDC() + 0x14f bytes    
    user32.dll!GetWindowLongW() + 0x127 bytes    
    user32.dll!DispatchMessageA() + 0xf bytes    
    mfc80d.dll!AfxInternalPumpMessage() Line 183    C++
    mfc80d.dll!CWinThread::PumpMessage() Line 896    C++
    [Managed to Native Transition]    
    FRC.exe!FFiREApp::PumpMessage() Line 748 + 0xb bytes    C++
    [Native to Managed Transition]    
    mfc80d.dll!CWinThread::Run() Line 625 + 0xd bytes    C++
    mfc80d.dll!CWinApp::Run() Line 894    C++
    mfc80d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f10, int nCmdShow=5) Line 47 + 0xd bytes    C++
    FRC.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f10, int nCmdShow=5) Line 33    C++
    FRC.exe!__tmainCRTStartup() Line 589 + 0x35 bytes    C
    FRC.exe!WinMainCRTStartup() Line 414    C
    mfc80d.dll!CWinThread::Run() Line 625 + 0xd bytes    C++
    mfc80d.dll!CWinApp::Run() Line 894    C++
    mfc80d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f10, int nCmdShow=5) Line 47 + 0xd bytes    C++
    FRC.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f10, int nCmdShow=5) Line 33    C++
    FRC.exe!__tmainCRTStartup() Line 589 + 0x35 bytes    C
    FRC.exe!WinMainCRTStartup() Line 414    C
    ntdll.dll!_RtlFreeHeapSlowly@12() + 0x207 bytes    
    ntdll.dll!_RtlFreeHeapSlowly@12() + 0x207 bytes    
    ntdll.dll!_LdrpGetProcedureAddress@20() + 0x136 bytes    
    ntdll.dll!_RtlAllocateHeap@12() + 0x117 bytes    

as you can read the Toolbar enters in a ::_DraggingStart(...) function -> it seems that we don’t exit properly

The window that kills the focus is

+        pWnd    0x04b8ea68 {CExtToolControlBar hWnd=0x00120dd2}    CWnd *

What can I do ?

Technical Support Jan 29, 2008 - 8:22 AM

A toolbar window never sets focus to itself. If this issue exists, then you can handle the WM_KILLFOCUS in your view window and set a breakpoint in the handler method. The call stack will allow you to see what happens and the handler method has a pointer to the window which requested focus.