📄 csdn_文档中心_using fonts in atl controls.htm
字号:
<LI>Open an existing ATL in-proc server project or create a
new one. <BR><BR>
<LI>Using the ATL Object Wizard, insert a new ATL control
into your project. Give the control a name, then select the
Stock Properties tab. From the Stock Properties tab, select
the Font property and insert it into your control.
Completing this step adds an interface definition such as
the following to your projects Interface Definition Language
file (.idl file). The interface definition in your .idl file
looks similar to the following: <PRE class=CODESAMP> [
object,
uuid(E882D672-878E-11D0-B00C-000000000000),
dual,
helpstring("INiceTextCtrl Interface"),
pointer_default(unique)
]
interface INiceTextCtrl : IDispatch
{
[propputref, id(DISPID_FONT)]
HRESULT Font([in]IFontDisp* pFont);
[propput, id(DISPID_FONT)]
HRESULT Font([in]IFontDisp* pFont);
[propget, id(DISPID_FONT)]
HRESULT Font([out, retval]IFontDisp** ppFont);
}; </PRE>In order for your control's Font property to
work correctly in most control containers, you need to move
this interface definition from outside the Library block in
your .idl file to inside the Library block. You also need to
remove the #import for Ucidl.idl from the .idl file. Your
.idl file now has a Library section that looks like the
following: <PRE class=CODESAMP> [
uuid(E882D665-878E-11D0-B00C-000000000000),
version(1.0),
helpstring("nicetext 1.0 Type Library")
]
library NICETEXTLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[ object,
uuid(E882D672-878E-11D0-B00C-000000000000),
dual,
helpstring("INiceTextCtrl Interface"),
pointer_default(unique)
]
interface INiceTextCtrl : IDispatch
{
[propputref, id(DISPID_FONT)]
HRESULT Font([in]IFontDisp* pFont);
[propput, id(DISPID_FONT)]
HRESULT Font([in]IFontDisp* pFont);
[propget, id(DISPID_FONT)]
HRESULT Font([out, retval]IFontDisp** ppFont);
};
[
uuid(E882D673-878E-11D0-B00C-000000000000),
helpstring("NiceTextCtrl Class") ]
coclass NiceTextCtrl
{
[default] interface INiceTextCtrl;
};
}; </PRE>This step also adds a member variable named
m_pFont to your control's implementation class to hold the
Font property. The get, put, and putref functions for the
stock Font property are implemented by ATL in the
CStockPropImpl class inside Atlctl.h. If you are
implementing a non- stock Font property, you have to add the
get, put, or putref functions manually if you are using
Visual C++ 4.2b. If you are using Visual C++ 5.0, you can
use the interface browser to add the property, which adds
the property get and put functions for you. <BR><BR>
<LI>Add a static variable of type FONTDESC to your control's
.cpp file. The FONTDESC structure holds the default
description of your Font property. You can create and
initialize the variable in the same step as follows: <PRE class=CODESAMP> static const FONTDESC _fontdesc =
{sizeof(FONTDESC), OLESTR("times new roman"), FONTSIZE( 14 ),
FW_BOLD, ANSI_CHARSET, TRUE, FALSE, FALSE }; </PRE><BR><BR>
<LI>Add an entry to your control's property map for the
stock Font such as the following: <PRE class=CODESAMP> PROP_ENTRY("Font", DISPID_FONT, CLSID_MSStockFont) </PRE>NOTE:
You also need to #include <ATLCTL.H> <BR><BR>
<LI>Change your control's drawing code so it uses your font
property to draw text. Here is an example of drawing code
you could add to an ATL control's OnDraw member function: <PRE class=CODESAMP> HFONT hStockFont=NULL,hOldFont=NULL;
CComQIPtr<IFont,&IID_IFont> pFont(m_pFont);
TCHAR msg[50];
wsprintf(msg,_T("Current Thread is %x"),GetCurrentThreadId());
if(pFont)
pFont->get_hFont(&hStockFont);
if(hStockFont)
hOldFont = (HFONT)SelectObject(di.hdcDraw,hStockFont);
DrawText(di.hdcDraw, msg, -1, &rc, DT_CENTER | DT_VCENTER |
DT_SINGLELINE);
if(hOldFont)
SelectObject(di.hdcDraw,hOldFont); </PRE>
<LI>It is recommended that you implement a sink object to
connect to the Font object's property notification source so
that your control updates its rendering with the correct
font properties when a client changes one of your font's
properties. COM-based fonts support an outgoing interface
based on the IPropertyNotifySink interface to notify font
users when properties of the font, such as name or weight,
are about to change and after they have been changed. To
receive notification of these changes, add a class to your
project that implements the IPropertyNotifySink interface.
Then, an instance of this class can be created by the
control and a pointer to it passed to the Font object's
connection point. Your control then receives notifications
from the Font object if its properties change, which allows
you to update your control's text accordingly. <BR><BR>The
following class implements an IPropertyNotifySink interface
and can be used for receiving notifications from a Font
object. This class also holds a back pointer to the parent
control object so that it can update the control when
properties change. This class is added to the control's
header file before the declaration of the control's class: <PRE class=CODESAMP> class CNiceTextCtrl; //forward definition of parent class
class ATL_NO_VTABLE CFontNotifyImpl :
public CComObjectRootEx<CComSingleThreadModel>
public IPropertyNotifySink
{
public:
CFontNotifyImpl():m_pParent(NULL){}
BEGIN_COM_MAP(CFontNotifyImpl)
COM_INTERFACE_ENTRY(IPropertyNotifySink)
END_COM_MAP()
public:
STDMETHOD(OnChanged)(DISPID dispid);
STDMETHOD(OnRequestEdit)(DISPID dispid){return S_OK;}
DWORD m_FontNotifyCookie;
void SetParent(CNiceTextCtrl *pParent){m_pParent = pParent;}
CNiceTextCtrl *m_pParent;
}; </PRE>To your control, add a protected member
variable that holds a sink object: <PRE class=CODESAMP> CComObject<CFontNotifyImpl> *m_pFontNotifySink; </PRE>Initialize
the sink object in your control's constructor: <PRE class=CODESAMP> CComObject<CFontNotifyImpl>::CreateInstance(&m_pFontNotifySink);
m_pFontNotifySink->SetParent(this); </PRE>
<LI>Initialize the font object for the control and hook up
the sink interface. A good place to do this is in
SetClientSite. SetClientSite is called when a control first
begins to interact with a container, soon after the control
object is created on behalf of a container. To override
SetClientSite. add it as a member of your control class by
adding the following to your control's header file inside
your class declaration: <PRE class=CODESAMP> STDMETHOD(SetClientSite)(LPOLECLIENTSITE pSite); </PRE>And
implement it in your object's .cpp file like this: <PRE class=CODESAMP> STDMETHODIMP CNiceTextCtrl::IOleObject_SetClientSite
(LPOLECLIENTSITE pSite)
{
HRESULT hr = CComControlBase::IOleObject_SetClientSite(pSite);
// Check to see if the container has an ambient font. If it does,
// clone it so your user can change the font of the control
// without changing the ambient font for the container. If there is
// no ambient font, create your own font object when you hook up a
// client site.
if(!m_pFont && pSite)
{
FONTDESC fd = _fontdesc;
CComPtr<IFont> pAF;
CComPtr<IFont> pClone;
if(SUCCEEDED(GetAmbientFont(&pAF)))
{
//clone the font
if(SUCCEEDED(pAF->Clone(&pClone)))
pClone->QueryInterface(IID_IFontDisp, (void**)&m_pFont);
}
else
{
OleCreateFontIndirect(&fd,IID_IFontDisp,(void**)&m_pFont);
}
//also, hook up a notify sink
if(m_pFont&&m_pFontNotifySink)
{
//smart pointers will release themselves
CComQIPtr<IConnectionPointContainer,&IID_IConnectionPointContainer>
pCPC(m_pFont);
CComPtr<IConnectionPoint> pCP;
if(pCPC)
{
pCPC->FindConnectionPoint(IID_IPropertyNotifySink,&pCP);
if(pCP)
{
pCP->Advise((IUnknown*)m_pFontNotifySink,
&m_pFontNotifySink->m_FontNotifyCookie);
}
}
}
}
return hr;
} </PRE><BR><BR>
<LI>Have the sink interface update the control when font
properties change: <PRE class=CODESAMP> STDMETHODIMP CFontNotifyImpl::OnChanged(DISPID dispid)
{
ATLTRACE(_T("OnChanged sink: %x\n"),this);
m_pParent->FireViewChange();
return S_OK;
} </PRE></LI></OL>
<P>Additional query words: font ATL stock property
</P></FONT><FONT face="Verdana, Arial, Helvetica" size=1>
<P>Keywords : kbfile kbprg kbsample kbusage kbATL200 kbATL210
kbCtrl kbFont kbATL300 kbGrpMFCATL <BR>Issue type : kbinfo
<BR>Technology :
</P><!--CONVLEGACY DELIMITER--></FONT></TD></TR></TBODY></TABLE><BR></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center bgColor=#006699 border=0 cellPadding=0 cellSpacing=0
width=770>
<TBODY>
<TR bgColor=#006699>
<TD align=middle bgColor=#006699 id=white><FONT
color=#ffffff>对该文的评论</FONT></TD>
<TD align=middle>
<SCRIPT
src="CSDN_文档中心_Using Fonts in ATL Controls.files/readnum.htm"></SCRIPT>
</TD></TR></TBODY></TABLE><BR>
<DIV align=center>
<TABLE align=center bgColor=#cccccc border=0 cellPadding=2 cellSpacing=1
width=770>
<TBODY>
<TR>
<TH bgColor=#006699 id=white><FONT
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<DIV align=center>
<TABLE border=0 width=770>
<TBODY>
<TR>
<TD>你没有登陆,无法发表评论。 请先<A
href="http://www.csdn.net/member/login.asp?from=/Develop/read_article.asp?id=3046">登陆</A>
<A
href="http://www.csdn.net/expert/zc.asp">我要注册</A><BR></TD></TR></TBODY></TABLE></DIV><BR>
<HR noShade SIZE=1 width=770>
<TABLE border=0 cellPadding=0 cellSpacing=0 width=500>
<TBODY>
<TR align=middle>
<TD height=10 vAlign=bottom><A
href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A
href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A
href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A
href="http://www.csdn.net/english">English</A> </TD>
<TD align=middle rowSpan=3><A
href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG
border=0 height=48
src="CSDN_文档中心_Using Fonts in ATL Controls.files/biaoshi.gif"
width=40></A></TD></TR>
<TR align=middle>
<TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
<TR align=middle>
<TD vAlign=top><FONT face=Verdana>Copyright © CSDN.net, Inc. All rights
reserved</FONT></TD></TR>
<TR>
<TD height=15></TD>
<TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--内容结束//--><!--结束//--></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -