Solved

ATL/COM: IPersistPropertyBag::Load

Posted on 2001-08-24
10
734 Views
Last Modified: 2013-11-25
i have a composite control, which contains another control..
i have a property in this control which i want to forward to the other one..
as a simpler example:
i have a property TestProperty, which is of the contained object.. i made a TestProperty in the composite control and in put/get code i just do something like

STDMETHODIMP CNMGrid::put_TestProperty(VARIANT_BOOL newVal)
{
   if(m_containedCtrl)
        return m_containedCtrl->put_TestProperty(newVal);
   else
        return S_OK;
}

i implement IPersistPropertyBagImpl and, as a result, my put_ methods are called when launching from VB (as for example)..
but! the problem is that those are called _before_ the composite control instantiates the contained windows..
that means it gets in put_TestProperty before the contained control is created, so m_containedCtrl is NULL..

how can i solve this problem?

1. to reload the properties, but i don't know how to obtain the PropertyBag that i need..
2. other ideas? :)

for 1. i've tried something like the following code, but it doesn't work (i get pPropBag NULL).. i'm not doing the right thing?

CComPtr<IPersistPropertyBag> pPersistPropBag;
CComPtr<IPropertyBag> pPropBag;
CComPtr<IOleClientSite> pOleClientSite;
CComPtr<IOleContainer> pOleContainer;

HRESULT hr = GetClientSite(&pOleClientSite);

if (SUCCEEDED(hr))
{
     hr = pOleClientSite->GetContainer(&pOleContainer);

     if (SUCCEEDED(hr))
     {
          pOleContainer->QueryInterface(IID_IPropertyBag, (LPVOID*)&pPropBag);

          if (SUCCEEDED(hr))
          {
               this->QueryInterface(IID_IPersistPropertyBag, (LPVOID*)&pPersistPropBag);
               pPersistPropBag->Load(pPropBag, NULL);
          }
     }
}

i hope i was clear.. even if to be so is something unusual at me..
0
Comment
Question by:lame_programmer
10 Comments
 

Author Comment

by:lame_programmer
ID: 6421653
i desperately need a solution :\
0
 
LVL 9

Accepted Solution

by:
ShaunWilde earned 300 total points
ID: 6423738
could you just store your property as a member of your class eg VARIANT_BOOL and then when you create your contained control use it to set the property of that control

eg

STDMETHODIMP CNMGrid::put_TestProperty(VARIANT_BOOL newVal)
{
  if(m_containedCtrl)
       return m_containedCtrl->put_TestProperty(newVal);
  else
  { // store it away
     m_varboolContained = newVal;
  }

  return S_OK;
}
0
 
LVL 9

Expert Comment

by:BeyondWu
ID: 6424123
Listening..
0
 
LVL 7

Expert Comment

by:peterchen092700
ID: 6424675
I guess you can't create the contained control earlier? ;)
Go with ShaunWilde's suggestion. Retriving the "original" Storage is impossible to do universally and safely.

0
 

Author Comment

by:lame_programmer
ID: 6427705
sorry for being late.. weekend...
i would go for what ShaunWilde said, i thought about it too, but i gaved a simple example - for what "i have for real" it's not very handful.. in fact i have 182 properties which i'll have to store :)
anyway.. if there won't be any answers i'll credit this one (since it solves my problem), even is not what i really wanted..
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:lame_programmer
ID: 6427711
"I guess you can't create the contained control earlier?"

this would fit my needs.. i can create an object earlier, but how i attach it to the hwnd of the one created?
0
 

Author Comment

by:lame_programmer
ID: 6427873
i've solved my problem in the following way (i'll describe samples of code):

- i have now a static label in the composite control
- i have an object of my type in the control
class ATL_NO_VTABLE CNMGrid :
     [..snip..]
     CComPtr<IMyContainedControl> m_pContained;

- i create an object of my type in the constructor of the composite control

CNMGrid::CNMGrid()
{
     [..snip..]
     
     m_pContained.CoCreateInstance(__uuidof(IMyContainedControl), NULL, CLSCTX_ALL);
}

- when the composite control receives WM_INITDIALOG i attach my object to the static's hwnd

LRESULT CNMGrid::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
     AtlAxAttachControl((IUnknown*)(m_pContained.p), GetDlgItem(IDC_STATIC), NULL);

     return 0;
}

maybe it helps - somewhere in future - anyone else who's having the same problem..
now, the points.. since the only solution i have is ShaunWilde i guess i'll accept that as an answer.. i should credit also peterchen, but i can't make everyone happy :\
0
 

Author Comment

by:lame_programmer
ID: 6427880
i haven't used it, because is something else than i wanted.. but it is a solution in almost all the cases :)
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6430091
thanks - but I feel unworthy - but thanks again
0
 

Author Comment

by:lame_programmer
ID: 6435808
any help worths something.. more than just 300 virtual points :)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now