Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ATL ActiveX control with unit test #10754

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "AxTestControl.h"

#pragma warning(push)
#pragma warning(disable: 4355) // 'this' : used in base member initializer list

CAxTestControl::CAxTestControl() : m_ctlButton(_T("Button"), this, 1), m_count(0)
{
m_bWindowOnly = TRUE;
}

#pragma warning(pop)

HRESULT CAxTestControl::FinalConstruct()
{
return S_OK;
}

void CAxTestControl::FinalRelease()
{
}

LRESULT CAxTestControl::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = CComControl<CAxTestControl>::OnSetFocus(uMsg, wParam, lParam, bHandled);
if (m_bInPlaceActive && !IsChild(::GetFocus()))
m_ctlButton.SetFocus();
return lRes;
}

LRESULT CAxTestControl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT rc;
GetWindowRect(&rc);
rc.right -= rc.left;
rc.bottom -= rc.top;
rc.top = rc.left = 0;
m_ctlButton.Create(m_hWnd, rc);
return 0;
}

STDMETHODIMP CAxTestControl::SetObjectRects(LPCRECT prcPos, LPCRECT prcClip)
{
IOleInPlaceObjectWindowlessImpl<CAxTestControl>::SetObjectRects(prcPos, prcClip);
int cx = prcPos->right - prcPos->left;
int cy = prcPos->bottom - prcPos->top;
::SetWindowPos(m_ctlButton.m_hWnd, NULL, 0, 0, cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
return S_OK;
}

void CAxTestControl::OnTextChanged()
{
m_ctlButton.SetWindowText(CString(m_bstrText));
Fire_OnTextChanged(m_bstrText);
}

LRESULT CAxTestControl::OnButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
Fire_OnButtonClick(++m_count);
Fire_OnClick();
return 0;
}

HRESULT CAxTestControl::Fire_OnTextChanged(BSTR text)
{
HRESULT hr = S_OK;
int cConnections = m_vec.GetSize();

for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
IDispatch* pConnection = static_cast<IDispatch*>(punkConnection.p);

if (pConnection)
{
CComVariant avarParams[1];
avarParams[0] = text;
CComVariant varResult;
DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
}
}

return hr;
}

HRESULT CAxTestControl::Fire_OnButtonClick(LONG count)
{
HRESULT hr = S_OK;
int cConnections = m_vec.GetSize();

for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
IDispatch* pConnection = static_cast<IDispatch*>(punkConnection.p);

if (pConnection)
{
CComVariant avarParams[1];
avarParams[0] = count;
CComVariant varResult;
DISPPARAMS params = { avarParams, NULL, 1, 0 };
hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
}
}

return hr;
}

HRESULT CAxTestControl::Fire_OnClick()
{
HRESULT hr = S_OK;
int cConnections = m_vec.GetSize();

for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
IDispatch* pConnection = static_cast<IDispatch*>(punkConnection.p);

if (pConnection)
{
CComVariant varResult;
DISPPARAMS params = { NULL, NULL, 0, 0 };
hr = pConnection->Invoke(DISPID_CLICK, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
}
}

return hr;
}

OBJECT_ENTRY_AUTO(__uuidof(AxTestControl), CAxTestControl);
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#pragma once

#ifndef STRICT
#define STRICT
#endif

#define _USRDLL
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW

#include <atlstr.h>
#include <atlbase.h>
#include <atlctl.h>

#include <Contract.h>

using namespace ATL;

class ATL_NO_VTABLE CAxTestControl :
public CComObjectRootEx<CComSingleThreadModel>,
public CStockPropImpl<CAxTestControl, IAxTestControl>,
public IPersistStreamInitImpl<CAxTestControl>,
public IOleControlImpl<CAxTestControl>,
public IOleObjectImpl<CAxTestControl>,
public IOleInPlaceActiveObjectImpl<CAxTestControl>,
public IViewObjectExImpl<CAxTestControl>,
public IOleInPlaceObjectWindowlessImpl<CAxTestControl>,
public IConnectionPointContainerImpl<CAxTestControl>,
public IConnectionPointImpl<CAxTestControl, &__uuidof(_IAxTestControlEvents)>,
public CComCoClass<CAxTestControl, &CLSID_AxTestControl>,
public CComControl<CAxTestControl>
{
public:
CContainedWindow m_ctlButton;
CComBSTR m_bstrText;
DWORD m_count;

CAxTestControl();
HRESULT FinalConstruct();
void FinalRelease();

DECLARE_PROTECT_FINAL_CONSTRUCT()
DECLARE_NO_REGISTRY()

DECLARE_OLEMISC_STATUS(0
| OLEMISC_RECOMPOSEONRESIZE
| OLEMISC_ACTSLIKEBUTTON
| OLEMISC_CANTLINKINSIDE
| OLEMISC_INSIDEOUT
| OLEMISC_ACTIVATEWHENVISIBLE
| OLEMISC_SETCLIENTSITEFIRST
)

BEGIN_COM_MAP(CAxTestControl)
COM_INTERFACE_ENTRY(IAxTestControl)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()

BEGIN_PROP_MAP(CAxTestControl)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
PROP_ENTRY_TYPE("Text", DISPID_TEXT, CLSID_NULL, VT_BSTR)
END_PROP_MAP()

BEGIN_CONNECTION_POINT_MAP(CAxTestControl)
CONNECTION_POINT_ENTRY(__uuidof(_IAxTestControlEvents))
END_CONNECTION_POINT_MAP()

BEGIN_MSG_MAP(CAxTestControl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
COMMAND_CODE_HANDLER(BN_CLICKED, OnButtonClicked)
CHAIN_MSG_MAP(CComControl<CAxTestControl>)
ALT_MSG_MAP(1)
END_MSG_MAP()

LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
STDMETHOD(SetObjectRects)(LPCRECT prcPos, LPCRECT prcClip);

// IViewObjectEx
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// IAxTestControl
void OnTextChanged();
LRESULT OnButtonClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
HRESULT Fire_OnTextChanged(BSTR text);
HRESULT Fire_OnButtonClick(LONG count);
HRESULT Fire_OnClick();
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:/we4055>) # 'conversion' : from

add_library(NativeTests SHARED
AccessibleObjectTests.cpp
AxTestControl.cpp
DllGetClassObject.cpp
DispatchImpl.cpp
RawErrorInfoUsageTest.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "olectl.h"
import "oaidl.idl";
import "ocidl.idl";

Expand All @@ -11,6 +12,21 @@ interface IBasicTest : IDispatch
[propput] HRESULT Int_Property([in] int val);
};

[
object,
uuid(424ddab6-a4b1-422f-93b9-7e254b28dbf0),
dual,
nonextensible,
pointer_default(unique)
]
interface IAxTestControl : IDispatch
{
[propput, bindable, requestedit, id(DISPID_TEXT)]
HRESULT Text([in] BSTR strText);
[propget, bindable, requestedit, id(DISPID_TEXT)]
HRESULT Text([out, retval] BSTR* pstrText);
};

[
uuid(0971AD7E-3D4A-4C44-B0A3-A518AC88DFE1)
]
Expand All @@ -35,4 +51,25 @@ library NativeTests
[default] interface IBasicTest;
interface ISupportErrorInfo;
}

[
uuid(726D447D-8F66-4330-9531-F591011DC7B7)
]
dispinterface _IAxTestControlEvents
{
properties:
methods:
[id(1)] void OnTextChanged([in] BSTR text);
[id(2)] void OnButtonClick([in] LONG count);
[id(DISPID_CLICK)] void OnClick();
};

[
uuid(4EABA135-7C8A-4DB8-B732-2A6AE511D7EB)
]
coclass AxTestControl
{
[default] interface IAxTestControl;
[default, source] dispinterface _IAxTestControlEvents;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

#include "RawErrorInfoUsageTest.h"
#include "StandardErrorInfoUsageTest.h"
#include "AxTestControl.h"

class CNativeTestsModule : public ATL::CAtlDllModuleT<CNativeTestsModule> {} _AtlModule;

STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID FAR* ppv)
{
Expand All @@ -17,5 +20,8 @@ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID FA
if (rclsid == __uuidof(StandardErrorInfoUsageTest))
return ClassFactoryBasic<StandardErrorInfoUsageTest>::Create(riid, ppv);

if (rclsid == __uuidof(AxTestControl))
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);

return CLASS_E_CLASSNOTAVAILABLE;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<comClass
clsid="{EA1FCB3A-277C-4C79-AB85-E2ED3E858201}"
threadingModel="Both" />
<!-- AxTestControl -->
<comClass
clsid="{4EABA135-7C8A-4DB8-B732-2A6AE511D7EB}"
threadingModel="Apartment" />
</file>

</assembly>
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,15 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<NativeProjectReference Include="..\InteropTests\NativeTests\CMakeLists.txt" CMakeProject="..\InteropTests\NativeTests\NativeTests.proj" BuildNative="true" />
</ItemGroup>

<Target Name="CopyTlbProjectFiles" BeforeTargets="CopyNativeProjectBinaries">
<ItemGroup>
<NativeProjectBinaries Include="$(NativeProjectOutputFolder)\*.tlb" />
<NativeProjectBinaries Include="$(NativeProjectOutputFolder)\*.manifest" />
</ItemGroup>
</Target>
</Project>
Loading
Loading