15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


SetFocus() from CMyTree::OnSelChanging()

GoroKhM1 -- gorokhm1@SMTP.ATG-NET.COM
Monday, August 26, 1996

     Environment: Win95, VC4.2
     
     I have a splitter window with a tree view in the left pane and a form 
     view in the right pane. Tree selection drives edit controls in the 
     form view.
     
     Here is the snippet from my program:
     
     void CMyTree::OnSelChanging(NMHDR* pNMHDR, LRESULT* pResult) 
     {
       // Called when selection begin to change.
       // TVN_SELCHANGING notification message.
       NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
       *pResult = 0;
     
       if (!m_pForm->IsDataValid())
       {
         *pResult = 1; // Cancel Select Changing
         return;
       }
     }
     
     BOOL CMyForm::IsDataValid()
     {
       if ( .. bad data ..)
       {
         CEdit* pEdit = (CEdit*)GetDlgItem(IDC_DATA);
         pEdit->SetSel(0, -1);
         pEdit->SetFocus();
         return FALSE;
       }
       return TRUE;
     }
     
     The problem:
     
     The method IsDataValid() set focus to bad data in IDC_DATA correctly 
     if called from any place in my program, except the call from 
     CMyTree::OnSelChanging().  In that case focus is set and immediately 
     returns to selected item in the tree view.
     
     How to SetFocus() ?
     
     Mark
     
     MarkG@usa.net




Rommel Songco -- rsongco@spectrasoft.com
Thursday, August 29, 1996

>      I have a splitter window with a tree view in the left pane and a
form=20
>      view in the right pane. Tree selection drives edit controls in the=
=20
>      form view.
>      The problem:
>      The method IsDataValid() set focus to bad data in IDC_DATA >
correctly=20
>      if called from any place in my program, except the call from=20
>      CMyTree::OnSelChanging().  In that case focus is set and
>immediately returns to selected item in the tree view.
>     =20
>      How to SetFocus() ?

Hi there!

	From the MFC docs, the TVN_SELCHANGING notification message notifies a
tree-view control's parent window that the selection is _about_ to change
from one item to another.  That means the focus will soon be given to the
newly selected item.  Thus changing the focus at this point to some other
control is futile.

	To solve your problem, prevent the selection from changing.  You can do
that by coding a message handler for TVN_SELCHANGING and return TRUE.=20
Since your code above doesn't return a value, I assume that you're using
the WM_NOTIFY message.  Try message reflection instead.  That is, use the
ON_NOTIFY_REFLECT macro in the child control=92s message map.  In your ca=
se,
that should be

ON_NOTIFY_REFLECT (TVN_SELCHANGING, OnSelChanging)

Regards,

Rommel Songco
rsongco@spectrasoft.com=09




GoroKhM1 -- gorokhm1@SMTP.ATG-NET.COM
Tuesday, September 03, 1996

My original question in a thread was:

>I have a splitter window with a tree view in the left pane and a form 
>view in the right pane. Tree selection drives edit controls in the form 
>view.
>
>Here is the snippet from my program:
>
>void CMyTree::OnSelChanging(NMHDR* pNMHDR, LRESULT* pResult) 
>{
>  // Called when selection begin to change. 
>  // TVN_SELCHANGING notification message.
>  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; 
>  *pResult = 0;
>
>  if (!m_pForm->IsDataValid())
>  {
>    *pResult = 1; // Cancel Select Changing 
>    return;
>  }
>}
>
>BOOL CMyForm::IsDataValid()
>{
>  if ( .. bad data ..)
>  {
>    CEdit* pEdit = (CEdit*)GetDlgItem(IDC_DATA); pEdit->SetSel(0, -1);
>    pEdit->SetFocus();
>    return FALSE;
>  }
>  return TRUE;
>}
>
>The problem:
>
>The method IsDataValid() set focus to bad data in IDC_DATA correctly 
>if called from any place in my program, except the call from 
>CMyTree::OnSelChanging().  In that case focus is set and immediately 
>returns to selected item in the tree view.
>
>How to SetFocus() ?
>

Unfortunately for me the following suggestion doesn't work:

>From the MFC docs, the TVN_SELCHANGING notification message notifies a
>tree-view control's parent window that the selection is _about_ to change 
>from one item to another.  That means the focus will soon be given to the 
>newly selected item.  Thus changing the focus at this point to some other 
>control is futile.
>
>To solve your problem, prevent the selection from changing.  You can do
>that by coding a message handler for TVN_SELCHANGING and return TRUE.
>Since your code above doesn't return a value, I assume that you're using 
>the WM_NOTIFY message.  Try message reflection instead.  That is, use the 
>ON_NOTIFY_REFLECT macro in the child controls message map.  In your case,
>that should be 
>
>       ON_NOTIFY_REFLECT (TVN_SELCHANGING, OnSelChanging)

I _do_ use ON_NOTIFY_REFLECT (TVN_SELCHANGING, OnSelChanging) in a message
map. Thanks to Class Wizard.

Initially in the method CMyTree::OnSelChanging(..) there is an assignment
  *pResult = 0; // Allow Select Changing
If data are not valid
  *pResult = 1; // Cancel Select Changing 
That works fine and selected item _remains_ selected.

The problem:

>The method IsDataValid() set focus to bad data in IDC_DATA correctly 
>if called from any place in my program, except the call from 
>CMyTree::OnSelChanging().  In that case focus is set and immediately 
>returns to selected item in the tree view.

The question:

How to SetFocus() to edit control with not valid data from inside 
CMyTree::OnSelChanging()?

-Mark

MarkG@usa.net




Mario Contestabile -- Mario_Contestabile.UOS__MTL@UOSMTL2.universal.com
Wednesday, September 04, 1996

[Mini-digest: 2 responses]

Your code seems to be correct at first glance.
I believe the problem resides in the fact that
you are setting the focus to a control in the right pane
of a splitter window, yet the left pane is active at that moment.

I'd try the following in your OnSelChanging(){
   *pResult = m_pForm->IsDataValid();
   pCFrameWnd->SetActiveView((CView*)SplitterWnd.GetPane(0, pResult));
}

mcontest@universal.com

=========StartSnip()========
>  // Called when selection begin to change. 
>  // TVN_SELCHANGING notification message.
>  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; 
>  *pResult = 0;
>
>  if (!m_pForm->IsDataValid())
>  {
>    *pResult = 1; // Cancel Select Changing 
>    return;
>  }
>}
>
>BOOL CMyForm::IsDataValid()
>{
>  if ( .. bad data ..)
>  {
>    CEdit* pEdit = (CEdit*)GetDlgItem(IDC_DATA); pEdit->SetSel(0, -1);
>    pEdit->SetFocus();
>    return FALSE;
>  }
>  return TRUE;
>}
>
>The problem:
>
>The method IsDataValid() set focus to bad data in IDC_DATA correctly 
>if called from any place in my program, except the call from 
>CMyTree::OnSelChanging().  In that case focus is set and immediately 
>returns to selected item in the tree view.
>
>How to SetFocus() ?
>

Unfortunately for me the following suggestion doesn't work:

>From the MFC docs, the TVN_SELCHANGING notification message notifies a
>tree-view control's parent window that the selection is _about_ to change 
>from one item to another.  That means the focus will soon be given to the 
>newly selected item.  Thus changing the focus at this point to some other 
>control is futile.
>
>To solve your problem, prevent the selection from changing.  You can do
>that by coding a message handler for TVN_SELCHANGING and return TRUE.
>Since your code above doesn't return a value, I assume that you're using 
>the WM_NOTIFY message.  Try message reflection instead.  That is, use the 
>ON_NOTIFY_REFLECT macro in the child controls message map.  In your case,
>that should be 
>
>       ON_NOTIFY_REFLECT (TVN_SELCHANGING, OnSelChanging)

I _do_ use ON_NOTIFY_REFLECT (TVN_SELCHANGING, OnSelChanging) in a message
map. Thanks to Class Wizard.

Initially in the method CMyTree::OnSelChanging(..) there is an assignment
  *pResult = 0; // Allow Select Changing
If data are not valid
  *pResult = 1; // Cancel Select Changing 
That works fine and selected item _remains_ selected.

The problem:

>The method IsDataValid() set focus to bad data in IDC_DATA correctly 
>if called from any place in my program, except the call from 
>CMyTree::OnSelChanging().  In that case focus is set and immediately 
>returns to selected item in the tree view.

The question:

How to SetFocus() to edit control with not valid data from inside 
CMyTree::OnSelChanging()?

-Mark

MarkG@usa.net
=========SnipEnd()====

-----From: "GoroKhM1" 

Hi Mario,

You suggested:

>Your code seems to be correct at first glance. 
>I believe the problem resides in the fact that
>you are setting the focus to a control in the right pane
>of a splitter window, yet the left pane is active at that moment.
>
>I'd try the following in your OnSelChanging(){
>  *pResult = m_pForm->IsDataValid();
>  pCFrameWnd->SetActiveView((CView*)SplitterWnd.GetPane(0, pResult));
>}

I tried this idea before e-mail question to MFC-L. It isn't working.
IsDataValid() set focus to edit control with not valid data. 
Immediately after "return" from OnSelChanging() focus is set back to the 
previously selected tree item. The edit control with not valid data
flashes with selected text.

The question:

How to SetFocus() to edit control with not valid data from inside 
CMyTree::OnSelChanging()?

- Mark

MarkG@usa.net




Ian Brown -- Ian.Brown@ait.co.uk
Thursday, September 05, 1996



     This sounds like a focus chain problem.
     
     If Windows is in the middle of a KillFocus/SetFocus sequence, then any 
     actions taken which affect the focus are going to be undone by Windows 
     when it finishes the chain of events with its final SetFocus.
     
     The best way around this (IMHO) is to change your SetFocus call to a 
     PostMessage to the appropriate window - ie:
     
        pEdit->PostMessage( WM_SETFOCUS, 0, 0 );
     
     This should place your focus change message at the end of the queue, 
     where it will be acted on after Windows has done its stuff.
     
     HTH
     
     Ian


______________________________ Reply Separator _________________________________
Subject: Re: SetFocus() from CMyTree::OnSelChanging()
Author:  mfc-l@netcom.com at Internet
Date:    05/09/96 08:06

     
     
     
-----From: "GoroKhM1" 
     
Hi Mario,
     
You suggested:
     
>Your code seems to be correct at first glance. 
>I believe the problem resides in the fact that
>you are setting the focus to a control in the right pane
>of a splitter window, yet the left pane is active at that moment. 
>
>I'd try the following in your OnSelChanging(){ 
>  *pResult = m_pForm->IsDataValid();
>  pCFrameWnd->SetActiveView((CView*)SplitterWnd.GetPane(0, pResult)); 
>}
     
I tried this idea before e-mail question to MFC-L. It isn't working. 
IsDataValid() set focus to edit control with not valid data. 
Immediately after "return" from OnSelChanging() focus is set back to the 
previously selected tree item. The edit control with not valid data 
flashes with selected text.
     
The question:
     
How to SetFocus() to edit control with not valid data from inside 
CMyTree::OnSelChanging()?
     
- Mark
     
MarkG@usa.net
     



GoroKhM1 -- gorokhm1@SMTP.ATG-NET.COM
Friday, September 06, 1996

Hi Ian,

Your suggestion
    pEdit->PostMessage( WM_SETFOCUS, 0, 0 );
works the same way as
    pEdit->SendMessage( WM_SETFOCUS, 0, 0 );

That messages show selected text (white on blue) in Edit Control, 
caret in it, and focus rectangle is back to tree item!

I think framework sends (or posts) message WM_SETFOCUS to selected tree item 
_after_ return from CMyTree::OnSelChanging(). 

It means that the question:

    How to SetFocus() to edit control with not valid data from inside 
    CMyTree::OnSelChanging()?

has the answer:

    You cannot do it at all.

-Mark

MarkG@usa.net





Koronthaly David -- dkoronth@blava-s.bratisla.ingr.com
Wednesday, September 11, 1996

There should be some hacks possible, but I haven't checked any of them.

I think you can do it with CBT (computer based training) hooks. Also
check implementation of DDX in MFC, I think it is doing something
similar. The last opportunity is to post self some message (or set up
timer) and set the focus later.

Regards,
David Koronthaly

>----------
>From: 	GoroKhM1[SMTP:gorokhm1@SMTP.ATG-NET.COM]
>Sent: 	6. september 1996 21:52
>To: 	mfc-l@netcom.com
>Subject: 	Re: SetFocus() from CMyTree::OnSelChanging()
>
>Hi Ian,
>
>Your suggestion
>    pEdit->PostMessage( WM_SETFOCUS, 0, 0 );
>works the same way as
>    pEdit->SendMessage( WM_SETFOCUS, 0, 0 );
>
>That messages show selected text (white on blue) in Edit Control, 
>caret in it, and focus rectangle is back to tree item!
>
>I think framework sends (or posts) message WM_SETFOCUS to selected tree
>item 
>_after_ return from CMyTree::OnSelChanging(). 
>
>It means that the question:
>
>    How to SetFocus() to edit control with not valid data from inside 
>    CMyTree::OnSelChanging()?
>
>has the answer:
>
>    You cannot do it at all.
>
>-Mark
>
>MarkG@usa.net
>
>
>




| Вернуться в корень Архива |