Я хочу создать элемент управления ActiveX, поддерживающий модальные и немодальные диалоги, которые можно использовать на нескольких вкладках IE9 ~ IE11 одновременно.Это означает, что всплывающее диалоговое окно элемента управления ActiveX на текущей вкладке IE не помешает нам перейти на другие вкладки IE, и эти диалоги появляются только на текущей вкладке IE.Сначала я создал приложение библиотеки динамических ссылок (DLL) ATL с именем AtlActiveX, используя ATL / C ++ от Visual Studio 2010. Затем добавьте элемент управления ActiveX с именем AtlActiveXCtl, указав параметр Разрешить слияние кода прокси / заглушки и параметров IObjectWithSite (поддержка объектов IE).,Затем добавьте ресурс диалога с именем IDD_DIALOG1.Если не упомянуто здесь, другие параметры остаются по умолчанию.Так как окна / диалоги должны поддерживаться, переменная-член m_bWindowOnly должна быть назначена в конструкторе CAtlActiveXCtl.После этого добавьте обработчик сообщения для сообщения WM_CREATE, отображая диалоговые окна в функции OnCreate.Полный код AtlActiveXCtl.h прилагается ниже.
Я ссылался на другой вопрос Отображение диалогового окна режима с ActiveX в StackOverflow.Три всплывающих диалога проверяются в функции OnCreate ().
#pragma once
#include "resource.h"
#include <atlctl.h>
#include "AtlActiveX_i.h"
using namespace ATL;
// Modeless dialog
class CModelessDialog : public CDialogImpl<CModelessDialog>
{
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP(CModelessDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
END_MSG_MAP()
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL &)
{
return 0;
}
LRESULT OnClose(UINT, WPARAM, LPARAM, BOOL &)
{
DestroyWindow();
return 0;
}
};
// CAtlActiveXCtl
class ATL_NO_VTABLE CAtlActiveXCtl :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IAtlActiveXCtl, &IID_IAtlActiveXCtl, &LIBID_AtlActiveXLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IOleControlImpl<CAtlActiveXCtl>,
public IOleObjectImpl<CAtlActiveXCtl>,
public IOleInPlaceActiveObjectImpl<CAtlActiveXCtl>,
public IViewObjectExImpl<CAtlActiveXCtl>,
public IOleInPlaceObjectWindowlessImpl<CAtlActiveXCtl>,
public ISupportErrorInfo,
public IObjectWithSiteImpl<CAtlActiveXCtl>,
public IQuickActivateImpl<CAtlActiveXCtl>,
public IDataObjectImpl<CAtlActiveXCtl>,
public IProvideClassInfo2Impl<&CLSID_AtlActiveXCtl, NULL, &LIBID_AtlActiveXLib>,
public CComCoClass<CAtlActiveXCtl, &CLSID_AtlActiveXCtl>,
public CComControl<CAtlActiveXCtl>
{
public:
CAtlActiveXCtl()
{
m_bWindowOnly = 1;
}
DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
OLEMISC_CANTLINKINSIDE |
OLEMISC_INSIDEOUT |
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST
)
DECLARE_REGISTRY_RESOURCEID(IDR_ATLACTIVEXCTL)
BEGIN_COM_MAP(CAtlActiveXCtl)
COM_INTERFACE_ENTRY(IAtlActiveXCtl)
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(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()
BEGIN_PROP_MAP(CAtlActiveXCtl)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY_TYPE("Property Name", dispid, clsid, vtType)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
BEGIN_MSG_MAP(CAtlActiveXCtl)
CHAIN_MSG_MAP(CComControl<CAtlActiveXCtl>)
DEFAULT_REFLECTION_HANDLER()
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
{
static const IID* const arr[] =
{
&IID_IAtlActiveXCtl,
};
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
// IViewObjectEx
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
// IAtlActiveXCtl
public:
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
IOleInPlaceFrame *pOleInPlaceFrame = NULL;
IOleInPlaceUIWindow *pOleInPlaceUIwindow = NULL;
IOleInPlaceSite *pOleInPlaceSite = NULL;
OLEINPLACEFRAMEINFO oleInPlaceFrameInfo;
oleInPlaceFrameInfo.cb = sizeof(oleInPlaceFrameInfo);
HRESULT hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (LPVOID *)&pOleInPlaceSite);
if (hr != S_OK)
return S_OK;
RECT rc1, rc2;
hr = pOleInPlaceSite->GetWindowContext(&pOleInPlaceFrame, &pOleInPlaceUIwindow, &rc1, &rc2, &oleInPlaceFrameInfo);
{
HWND hWndTop = NULL;
pOleInPlaceSite->GetWindow(&hWndTop);
pOleInPlaceFrame->EnableModeless(TRUE);
::EnableWindow(hWndTop, FALSE);
//[1] Message box, cannot switch tab page
MessageBox(L"Hello, world!", L"MSG", MB_OK);
//[2] Modal dialog, cannot switch tab page
CSimpleDialog<IDD_DIALOG1> dlg;
dlg.DoModal(hWndTop);
//[3] Modeless dialog, can switch tab page, but always stays on top of IE browser
CModelessDialog *pDlg = new CModelessDialog;
pDlg->Create(hWndTop);
pDlg->ShowWindow(SW_SHOWNORMAL);
pOleInPlaceFrame->EnableModeless(FALSE);
::EnableWindow(hWndTop, TRUE);
}
return 0;
}
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
// Set Clip region to the rectangle specified by di.prcBounds
HRGN hRgnOld = NULL;
if (GetClipRgn(di.hdcDraw, hRgnOld) != 1)
hRgnOld = NULL;
bool bSelectOldRgn = false;
HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
if (hRgnNew != NULL)
bSelectOldRgn = (SelectClipRgn(di.hdcDraw, hRgnNew) != ERROR);
Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("AtlActiveXCtl");
TextOut(di.hdcDraw,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
if (bSelectOldRgn)
SelectClipRgn(di.hdcDraw, hRgnOld);
return S_OK;
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
};
OBJECT_ENTRY_AUTO(__uuidof(AtlActiveXCtl), CAtlActiveXCtl)
Модальные и немодальные диалоги должны поддерживаться в элементах управления ActiveX на вкладках IE11, как и в простых приложениях с графическим интерфейсом Win32.Может кто-нибудь любезно помочь мне решить эту проблему?