这些问题是以前在csdn当版主是一些朋友整理的,今天找到了,贴到这里来!
SIZEL size = {24, 24};
AtlPixelToHiMetric(&size, &m_sizeExtent);
m_sizeNatural = m_sizeExtent;
{
return DoVerbProperties(NULL, ::GetActiveWindow() );
}
{
if(SUCCEEDED(ISpecifyPropertyPages_GetPages(pPages,NULL))
{
pPages->cElems += 1;
pPages->pElems =
(GUID *)::CoTaskMemAlloc(pPages->cElems * sizeof(CLSID));
pPages->pElems[pPages->cElems - 1] = CLSID_General;
}
else
return E_FAIL;
}
{
HINSTANCE hInstance = ::LoadLibrary( szPath );
if ( 0 == hInstance )
{
return ::GetLastError();
}
typedef void (FAR PASCAL *REGSERVER)(void);
REGSERVER RegServer = (REGSERVER) ::GetProcAddress( hInstance, _T( "DllRegisterServer" ));
if ( 0 == RegServer )
{
::FreeLibrary( hInstance );
return ::GetLastError();
}
RegServer();
::FreeLibrary( hInstance );
}
...
class ATL_NO_VTABLE CNoteCtl :
...
STDMETHOD(SetExtent)(DWORD dwDrawAspect, SIZEL *psizel)
{
ATLTRACE(_T("SetExtent sizing control to 1000x1000 "));
psizel->cx = psizel->cy = 1000;
return IOleObjectImpl<CNoteCtl>::SetExtent(dwDrawAspect, psizel);
}
...
};
{
SIZEL szlPixels, szlMetric;
szlPixels.cx = cx;
szlPixels.cy = cy;
AtlPixelToHiMetric(&szlPixels, &szlMetric);
// IOleObjectImpl
SetExtent(DVASPECT_CONTENT, &szlMetric);
// update control sizing...
m_rcPos.right= m_rcPos.left + cx;
m_rcPos.bottom= m_rcPos.top + cy;
if (m_spInPlaceSite != NULL) {
// needed for IE to accept the resizing
m_spInPlaceSite->OnPosRectChange(&m_rcPos);
}
SetFocus();
{
BOOL bUserMode = TRUE;
HRESULT hRet = GetAmbientUserMode(bUserMode);
if (FAILED(hRet) || bUserMode)
{
return TRUE;
}
return FALSE;
}
{
BOOL bUserMode;
GetAmbientUserMode( bUserMode );
if (! bUserMode )
return CTL_E_GETNOTSUPPORTED;
*pTest = 100;
return S_OK;
}
#define RELEASE_OBJECT( ptr )if (ptr) { IUnknown *pUnk = (ptr); (ptr) = NULL; pUnk->Release(); }
#define QUICK_RELEASE(ptr) if (ptr) ((IUnknown *)ptr)->Release();
ISimpleFrameSite* m_pSimpleFrameSite;
m_pSimpleFrameSite = NULL;
QUICK_RELEASE(m_pSimpleFrameSite);
STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
{
HRESULT hr = IOleObjectImpl<你的控件类>::SetClientSite(pClientSite);
RELEASE_OBJECT(m_pSimpleFrameSite);
if( pClientSite != NULL )
pClientSite->QueryInterface( IID_ISimpleFrameSite,
(void **)&m_pSimpleFrameSite);
return hr;
}
WNDPROC m_fnOldWindowProc;
HWND Create( HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
DWORD dwStyle = WS_CHILD | WS_VISIBLE, DWORD dwExStyle = 0, UINT nID = 0 )
{
HWND hWnd = CWindowImpl<你的控件类>::Create( hWndParent, rcPos,
szWindowName, dwStyle, dwExStyle, nID);
if (hWnd)
{
::SetProp(hWnd, "ABC", static_cast<HANDLE> ((你的控件类*) this));
m_fnOldWindowProc = (WNDPROC) ::SetWindowLong( hWnd, GWL_WNDPROC, (LONG) SimpleFrameWindowProc);
}
return hWnd;
}
static LRESULT CALLBACK SimpleFrameWindowProc( HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK 你的控件类::SimpleFrameWindowProc( HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
你的控件类* pThis = static_cast<你的控件类*> (::GetProp(hWnd, "ABC"));
WNDPROC fnOldWindowProc = pThis->m_fnOldWindowProc;
LRESULT lResult;
BOOL bProcess = TRUE;
DWORD dwCookie;
HRESULT hr = E_FAIL;
if(pThis->m_pSimpleFrameSite)
{
hr = pThis->m_pSimpleFrameSite->PreMessageFilter(hWnd, uMsg, wParam,
lParam, &lResult, &dwCookie);
bProcess = (hr != S_FALSE);
}
if (bProcess)
lResult = fnOldWindowProc(hWnd, uMsg, wParam, lParam);
if(pThis->m_pSimpleFrameSite && bProcess)
{
pThis->m_pSimpleFrameSite->PostMessageFilter( hWnd, uMsg, wParam, lParam,
&lResult, dwCookie);
}
return lResult;
}
'MiscStatus' = s '0'
{
'1' = s '131473'
}
'MiscStatus' = s '0'
{
'1' = s '197009'
}
2.编辑Dialog。
3.在你的控件类中加入内部成员变量(例如:CMyDialog m_dlg)。
4.在你的控件中映射消息WM_CREATE,在消息处理函数里创建Dialog(例如:m_dlg.Create(m_hWnd))
2.产生Dialog资源,并设置ID为IDD_ABOUTBOX。
3.在你的控件中加入以下代码:
class CAboutDlg : public CDialogImpl<CAboutDlg>
{
public:
enum { IDD = IDD_ABOUTBOX };
BEGIN_MSG_MAP(CAboutDlg)
COMMAND_ID_HANDLER(IDOK, OnOK)
END_MSG_MAP()
HRESULT OnOK(WORD, WORD, HWND, BOOL&)
{
EndDialog(0);
return 0;
}
};
CAboutDlg dlg;
dlg.DoModal();
LPARAM lParam, BOOL& bHandled)
{
DWORD dwStyle = GetWindowLong(GWL_STYLE);
dwStyle |= WS_VSCROLL | WS_HSCROLL;
SetWindowLong(GWL_STYLE, dwStyle);
return 0L;
}
{
switch(pMsg->wParam)
{
case VK_UP:
{
::SendMessage(m_hWnd, WM_VSCROLL,
SB_LINEUP, MAKELONG(0,m_hWnd));
break;
}
case VK_DOWN:
{
::SendMessage(m_hWnd, WM_VSCROLL,
SB_LINEDOWN, MAKELONG(0,m_hWnd));
break;
}
//以上面相似:
// case VK_LEFT:
// case VK_RIGHT:
// case VK_PRIOR:
// case VK_NEXT:
}
return S_FALSE;
public CComObjectRootEx<CComSingleThreadModel>,
...
// Derive from IObjectSafety
public IObjectSafety
{
...
BEGIN_COM_MAP(CNoteCtl)
COM_INTERFACE_ENTRY(INoteCtl)
COM_INTERFACE_ENTRY(IDispatch)
...
// Add it to our interface map
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
...
// IObjectSafety implementation
STDMETHODIMP GetInterfaceSafetyOptions( REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions )
{
ATLTRACE(_T("CNoteCtl::GetInterfaceSafetyOptions() "));
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = *pdwSupportedOptions;
return S_OK;
}
STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
ATLTRACE(_T("CNoteCtl::SetInterfaceSafetyOptions "));
return S_OK;
}...
};
CMyCtl(){ static FONTDESC _fontDesc = { sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE( 12 ), FW_BOLD, ANSI_CHARSET, FALSE, FALSE, FALSE }; OleCreateFontIndirect( &_fontDesc,IID_IFontDisp,(void **)&m_pFont );}
//取得字体CComQIPtr<IFont, &IID_IFont> pFont( m_pFont使用它... if ( hOldFont ) SelectObject( hdc, hOldFont );} );if ( pFont ){ HFONT hOldFont = 0; HFONT hFont; pFont->get_hFont( &hFont ); hOldFont = (HFONT) SelectObject( hdc, hFont ); //
#include <olectl.h>import "oaidl.idl";[ uuid(E63A22F1-9BD3-11D0-A6D7-0000837E3100), version(1.0), helpstring("NoteIt 1.0 Type Library")]library NOTEITLib{ importlib("stdole32.tlb"); importlib("stdole2.tlb"); // Interface is now inside the library block [ object, uuid(E63A2306-9BD3-11D0-A6D7-0000837E3100), dual, helpstring("INoteCtl Interface"), pointer_default(unique) ] interface INoteCtl : 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); ... };...}
BSTR inFrom, BSTR inReply)
{
HRESULT hr = S_OK;
{
_com_error(hr);
}
catch (_com_error& e) {
hr = Error((BSTR)e.Description(), e.HelpContext(), e.HelpFile(),e.GUID(), e.Error());
ATLTRACE("com error: %d - %s ", e.Error(), (const char*)e.Description());
}
return hr;
}
1 = <verb1>
2 = <verb2>
3 =
OLEVERBATTRIB_ONCONTAINERMENU = 2
{
ForceRemove {E14A8DEA-8C72-11D1-891C-00C04FA3FB11} = s 'X Class'
{
ProgID = s 'X.X.1'
VersionIndependentProgID = s 'X.X'
ForceRemove 'Programmable'
...
'verb'
{
'1' = s '&Play,0,2'
'2' = s '&Transpose,0,2'
'3' = s '&Detune,0,2'
'4' = s '&Properties,0,2'
}
...
}
}
LPMSG lpmsg,
IOleClientSite *pActiveSite,
LONG lindex,
HWND hwndParent,
LPCRECT lprcPosRect)
{
if (iVerb == 1)//The verb number mentioned in the .rgs file
{
//Do whatever you want
}
else if(iVerb == 2)
{
}
?
?
return IOleObjectImpl<ClassName>::DoVerb(iVerb, lpmsg,
pActiveSite, lindex, hwndParent, lprcPosRect);
}
同理对于方法也生效。
HRESULT MyFunc([in]BSTR szName,[in, optional] VARIANT Param1, [out, optional] VARIANT Param2)
你在MyFunc程序中得检查Param1.vt是否为VT_EMPTY,如果是,用户未使用该参数。
在你的IDL文件中加入如下相似的代码:
{
[helpstring("Left")]Left=0,
[helpstring("Center")]Center=1,
[helpstring("Right")]Right=2,
}FontAlign;
[propget, id(2), helpstring("对齐方式")] HRESULT Align([out, retval] FontAlign *pVal);
[propput, id(2), helpstring("对齐方式")] HRESULT Align([in] FontAlign newVal);
在接下来的接口定义中添加属性Align时,属性的数据类型就填FontAlign,其它操作照常。编译完以后,你就应该在VB Project中的Object Browser中看到有这么一个枚举类型。在控件属性中选中Align时,就会有个Combo Box让你选择FontAlign中的一个值。
同样,VARIANT_BOOL和BOOL之间也有区别:BOOL为long,在BOOL中,TURE为1,FALSE为0。VAIRNAT_BOOL为short,在VARIANT_BOOL中,VARIANT_TRUE为-1(0xFFFF),VARIANT_FALSE为0(0x0000)。并且VARIANT_BOOL是和VB中的Boolean相同的,就像BSTR和String的关系一样。所以,在自动化组件及控件中应该使用VARIANT_BOOL。
void CMyControl::GetArray( VARIANT FAR* pVariant ){ //商业代码 int nCount = GetCount();
//定义维数 SAFEARRAYBOUND saBound[1]; //定义数组指针对性 SAFEARRAY* pSA; saBound[0].cElements = nCount; saBound[0].lLbound = 0; //创建数组 pSA = SafeArrayCreate( VT_BSTR, 1, saBound ); for( long i = 0; i < nCount; i++ ) { BSTR bstr; //商业代码 bstr = GetItem( i ).AllocSysString(); //给数组赋值 SafeArrayPutElement( pSA, &i, bstr ); ::SysFreeString( bstr ); } // 初始化传递的参数 VariantInit( pVariant ); //设置返值的类型为数组 pVariant->vt = VT_ARRAY | VT_BSTR; pVariant->parray = pSA;}
Dim t As Variant Dim i as Integer MyControl1.GetArray t For i = 0 To MyControl1.Count - 1 ListBox.AddItem t( i ) Next i
{
HWND hwnd = NULL;
HRESULT hr;
//*****这段代码在VC++ v4.1工作
if (m_pInPlaceSite != NULL)
{
m_pInPlaceSite->GetWindow(&hwnd);
return hwnd;
}
//****** 这段代码在Visual Basic工作
LPOLECLIENTSITE pOleClientSite = GetClientSite();
if ( pOleClientSite )
{
IOleWindow* pOleWindow;
hr = pOleClientSite->QueryInterface( IID_IOleWindow, (LPVOID*)
&pOleWindow );
if ( pOleWindow )
{
pOleWindow->GetWindow( &hwnd );
pOleWindow->Release();
return hwnd;
}
}
return NULL;
}
{
if ( m_ambientDispDriver.m_lpDispatch && AmbientUserMode() )
RecreateControlWindow();//商业代码
}
WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(IsUserMode())
{
InPlaceActivate(OLEIVERB_UIACTIVATE);
}
return 0;
}
bHandled)
{
CComControl<CJazzControl>::OnSetFocus (uMsg,
wParam, lParam, bHandled);
if (IsUserMode())
{
InPlaceActivate (OLEIVERB_UIACTIVATE);
m_ChildControl.SetFocus();
}
return 0;
}
{
if (
((pMsg->message >= WM_KEYFIRST) &&
(pMsg->message <= WM_KEYLAST))
&&
((pMsg->wParam == VK_TAB) ||
(pMsg->wParam == VK_RETURN))
)
{
CComQIPtr<IOleControlSite,&IID_IOleControlSite>
spCtrlSite(m_spClientSite);
if(spCtrlSite)
{
return spCtrlSite->TranslateAccelerator(pMsg, 0);
}
}
return S_FALSE;
}
(pMsg->wParam == VK_DOWN)||
(pMsg->wParam == VK_LEFT) ||
(pMsg->wParam == VK_RIGHT))
{
::IsDialogMessage(m_hWnd, pMsg);
return S_OK;
}
{
::SendMessage(m_hWnd,WM_VSCROLL,
SB_LINEUP,MAKELONG(0,m_hWnd));
return S_FALSE;
}
{
if(!pCI)
{
return E_POINTER;
}
pCI->hAccel = NULL; //load your accelerators here, if any
pCI->cAccel = 0;
pCI->dwFlags = 0;
return S_OK;
}
[in] short nIndex, [out, retval] short *pVal);
[propput, id(4), helpstring("Indexed Property ")] HRESULT ParamProp(
[in] short nIndex, [in] short newVal);
BOOL fClearDirty ,
ATL_PROPMAP_ENTRY* pMap
)
{
if(!pStm)
{
return E_POINTER;
}
for(UINT nIndex = 0; nIndex < 12; nIndex++)
{
if(FAILED(pStm->Write(&(m_nColor[nIndex]),
sizeof(m_nColor[nIndex]), NULL))
{
return E_UNEXPECTED;
}
}
//调用默认的基类来实现存储单属性值PROP_MAP
return CComControlBase::IPersistStreamInit_Save(pStm, fClearDirty, pMap);
}
if (m_bWndLess)
{
HDC hDC;
HWND hWnd;
// Get the HDC from the client
m_spInPlaceSite->GetDC(NULL, OLEDC_NODRAW, &hDC);
// Get the HWND from the HDC
hWnd = WindowFromDC(hDC);
m_spInPlaceSite->ReleaseDC(hDC);
}
注意:不要乱动那个hWnd因为这个东西不是你的。
1.建立一个ALT的project,加入ALT对象选 controls选 full controls (也可以选别的)Next选Stock properties将Picture 加入 supported //这样, 会为控件生成一个picture属性,以及一个预制的 picture 属性对话框,方便选择图片。OK//m_pPicture 是一个 IPictureDisp.
//由于M$的一个BUG 导致 build时 有三个warning 先不要管它, 后面会有解决办法
2.修改 HRESULT OnDraw(ATL_DRAWINFO& di)如下
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
/////////////////////////////////////draw our picture
LPPICTURE pPict ;
DWORD dwAttr ;
OLE_XSIZE_HIMETRIC cxSrc;
OLE_YSIZE_HIMETRIC cySrc;
if ((m_pPicture != NULL) &&SUCCEEDED(m_pPicture->QueryInterface(IID_IPicture, (LPVOID*)&pPict)))
{
pPict->get_Attributes(&dwAttr);
if(dwAttr==S_OK)
{
pPict->get_Width(&cxSrc);
pPict->get_Height(&cySrc);
pPict->Render(di.hdcDraw,rc.left, rc.top, rc.right, rc.bottom,0,0,cxSrc,cySrc,&rc);
}
}
///////////////////////////////////////finished draw
SetTextAlign(di.hdcDraw, TA_CENTER¦TA_BASELINE);
LPCTSTR pszText = _T("ATL 3.0 : catest");
TextOut(di.hdcDraw,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
return S_OK;
}
DEFINE_GUID(<<name>>, 0xCAF53C68, 0xA94C, 0x11D2, 0xBB, 0x4A, 0x00, 0xC0, 0x4F, 0xA3, 0x30, 0xA6);