描述:
在进行ActiveX开发时,会用到属性页,你可以自己添加系统属性页也可以自己定制属性页,这些属性页都是添加在属性单(CPropertySheet)上的。我的问题是,怎样才能在控件运行的时候,也可以把属性单显示出来。就是想知道控件默认的属性单是什么?谢谢,那位大虾可以告知小弟~~
解决方案1:
我在一个网站让发现的,给你贴过来,试试看
Can I display my control's property page at run-time?
Original Question:
We would like our OCX end users to be able to pop up the design-time OLE property page at run-time, as well. I tried a quick hack to make this happen:
1) I trapped the right-button mouse click
2) In the mouse-click message handler, I invoked COleControl::OnProperties(0, NULL, NULL)
This worked OK, except
a) The Property page was modeless, rather than modal
b) because of (a), I was able to popup several copies of the property page!
c) The property page sometimes would eat the first (activating) mouse click before it would respond.
Now, Visual Basic pops up the properties in a modal way ... is there any way for me to get Visual Basic (or the container, in general) to display the properties at run-time as it does at design time?
Answer:
I did a little research on your problem and here's what I've come up with.
According to the documentation for IOleControlSite, if a control wants to display a property sheet, it must first ask the container to do it, something like this:
m_pControlSite->ShowPropertyFrame();
This is basically because the container may have an extended control and so would possibly like to add its property pages to those of the control. So, a control should call IOleControlSite::ShowPropertyFrame if it wants to display its property pages. This will allow the container to "handle" the property sheet. If the call returns E_NOTIMPL, then the control must perform the work itself. But, if it returns S_OK, then the container has successfully displayed it and everything should be just fine. This is exactly what COleControl::OnProperties does. You would expect then that all you need to do is call OnProperties from your control when you want to display its property pages. Well, as you've noticed, at least in Visual Basic anyway, the container shows the property sheet modeless. It also allows multiple instances of the property sheet.
To solve the problem, I just cut the code from COleControl::OnProperties and placed in the OnRButtonDown handler and everything seemed to work. It may not be the "recommended way", but it works. I've only tried it in VB though, this approach may not work in other containers (e.g. VC++). Let me know what you find out. Here's the code for OnRButtonDown.
void CMyCtrl::OnRButtonDown( UINT nFlags, CPoint point )
{
CWnd* pWnd = GetParent();
HWND hWndParent;
// Various ways to get the parent window
if ( pWnd )
hWndParent = pWnd->GetSafeHwnd();
else
hWndParent = NULL;
hWndParent = GetApplicationWindow();
// Need to include <afxpriv.h> for this macro
USES_CONVERSION;
HRESULT hr;
LPUNKNOWN pUnk = GetIDispatch(FALSE);
CWnd* pWndOwner = CWnd::GetSafeOwner(CWnd::FromHandle(hWndParent));
HWND hWndOwner = pWndOwner->GetSafeHwnd();
LCID lcid = AmbientLocaleID();
ULONG cPropPages;
LPCLSID pclsidPropPages = GetPropPageIDs(cPropPages);
RECT rectParent;
RECT rectTop;
::GetWindowRect(hWndParent, &rectParent);
::GetWindowRect(hWndOwner, &rectTop);
TCHAR szUserType[256];
GetUserType(szUserType);
// Display the property page modally
PreModalDialog(hWndOwner);
hr = OleCreatePropertyFrame(hWndOwner, rectParent.left - rectTop.left,
rectParent.top - rectTop.top, T2COLE(szUserType), 1, &pUnk,
cPropPages, pclsidPropPages, lcid, NULL, 0);
PostModalDialog(hWndOwner);
说到属性单,俺也不熟啊!
不过属性页也是一个COM对象,一般来说在设计时由编译器提供一个表单来放置,设计时是指使用这个控件来进行开发的时候;
你的“在控件运行的时候,也可以把属性单显示出来”的意思如果是指已经开发完运行时的话,就需要显示这样的属性页需要你自己装载属性页对象了。
不过这有意义吗?属性页的工作是简化控件设计时的工作量,不是在运行时来改控件属性的。