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
>
>
>
| Вернуться в корень Архива
|