From: dushkin on
Hi All,
I have an MFC application with a TreeView and a CDockablePane
Properties Window.

When I select a tree item - I display its properties in the properties
window. That works.

But I don't know how to change the tree item properties when I change
the values in the properties window. My problem is in getting the
values from the properties grid.

I tried to override EndEditItem method like this:

BOOL CMyMFCPropertyGridCtrl::EndEditItem(BOOL bUpdateData)
{
CMFCPropertyGridProperty* currProperty = GetCurSel();

if(currProperty)
{
//I don't like this implementation! Any suggestions???
((CMyTreeView*)(((CMainFrame*) AfxGetMainWnd()))->GetActiveView()))-
>UpdateTreeItemFromPropWnd(currProperty->GetName(), currProperty-
>GetValue());
}
return CMFCPropertyGridCtrl::EndEditItem();
}

I an trying to catch the event of ending the value editing. But what
is this "ending" of this operation. For example, when I edit and press
"return" button - the event is not called!

Any help will be blessed.
Thanks!
From: dushkin on
Help... anyone??? :-(
From: dushkin on
On Jun 13, 9:21 am, dushkin <talt...(a)gmail.com> wrote:
> Help... anyone??? :-(

Well, lucky me to find the solution... `-)

I derived a class from CMFCPropertyGridProperty and overridden
OnEndEdit().

The default implementation of OnEditEnd() is something like:

ASSERT_VALID(this);

m_bInPlaceEdit = FALSE;
m_bButtonIsFocused = FALSE;

OnDestroyWindow();

//new line will come here...

return TRUE;

So I added the following line, right after the OnDestroyWindow() line:

((CMyView*)(((CMainFrame*)(AfxGetMainWnd()))->GetActiveView()))-
>UpdateTreeItemFromPropWnd(GetName(), GetValue());

I know it is not such an elegant solution, but at least it works.
I will try now to find a more neater way to update the tree view,
maybe with some kind of listeners...
From: Joseph M. Newcomer on
See below...
On Thu, 10 Jun 2010 06:25:10 -0700 (PDT), dushkin <dushkin(a)012.net.il> wrote:

>Hi All,
>I have an MFC application with a TreeView and a CDockablePane
>Properties Window.
>
>When I select a tree item - I display its properties in the properties
>window. That works.
>
>But I don't know how to change the tree item properties when I change
>the values in the properties window. My problem is in getting the
>values from the properties grid.
>
>I tried to override EndEditItem method like this:
>
>BOOL CMyMFCPropertyGridCtrl::EndEditItem(BOOL bUpdateData)
>{
> CMFCPropertyGridProperty* currProperty = GetCurSel();
>
> if(currProperty)
> {
> //I don't like this implementation! Any suggestions???
> ((CMyTreeView*)(((CMainFrame*) AfxGetMainWnd()))->GetActiveView()))-
>>UpdateTreeItemFromPropWnd(currProperty->GetName(), currProperty-
>>GetValue());
****
You're right not to like this code. It is horrible, and essentially a nightmare. The
CORRECT approach is to SendMessage to the main frame a user-defined message, e.g.,
CString propertyname;
CString newvalue;
...fetch these from the property pane...
AfxGetMainWnd()->SendMessage(UWM_PROPERTY_CHANGED,
(LPARAM)&propertyname,
(WPARAM)&newvalue);
and stop right there.

What I would probably do in the mainframe is send the message to the current view, which
would call a method of the CDocument-class,
void CMyDocument::SetProp(const CString & propname, const CString & value);
and let it worry about what gets set.

The downside is that every view has to have a handler for this message, since you don't
know which view might be active.

LRESULT OnPropertyChange(WPARAM wParam, LPARAM lParam)
{
CString * prop = (CString *)wParam;
CString * val = (CString *)lParam;
GetDocument()->SetProp(*prop, *val);
return 0;
}

Always maintain abstraction. When you find yourself doing horrible casts and having to
include header files that you should not need, you have a bad architecture.
joe
****
> }
> return CMFCPropertyGridCtrl::EndEditItem();
>}
>
>I an trying to catch the event of ending the value editing. But what
>is this "ending" of this operation. For example, when I edit and press
>"return" button - the event is not called!
****
I don't have a good answer for that problem. However, there are some fascinating problems
about how <enter> is handled when controls are embedded in MFC views; the classic one is
how to handle <enter> when editing a tree-control item (the code, however, is massively
buggy; I discuss this in my MSDN Errors and Omissions articles)
joe
****
>
>Any help will be blessed.
>Thanks!
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Mon, 14 Jun 2010 00:12:05 -0700 (PDT), dushkin <taltene(a)gmail.com> wrote:

>On Jun 13, 9:21�am, dushkin <talt...(a)gmail.com> wrote:
>> Help... anyone??? :-(
>
>Well, lucky me to find the solution... `-)
>
>I derived a class from CMFCPropertyGridProperty and overridden
>OnEndEdit().
****
I would have thought this was what you were *starting from*.
****
>
>The default implementation of OnEditEnd() is something like:
>
> ASSERT_VALID(this);
>
> m_bInPlaceEdit = FALSE;
> m_bButtonIsFocused = FALSE;
>
> OnDestroyWindow();
>
> //new line will come here...
>
> return TRUE;
>
>So I added the following line, right after the OnDestroyWindow() line:
>
> ((CMyView*)(((CMainFrame*)(AfxGetMainWnd()))->GetActiveView()))-
>>UpdateTreeItemFromPropWnd(GetName(), GetValue());
****
As I indicated in an earilier reply, there is nothing justifiable about any part of the
above code. You should not be casting the AfxGetMainWnd to anything, and the very
presence of CMyView* indicates a deep design error that should not exist.
joe

>
>I know it is not such an elegant solution, but at least it works.
>I will try now to find a more neater way to update the tree view,
>maybe with some kind of listeners...
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm