/*
 * Copyright 2005 Jacek Caban
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "ocidl.idl";

cpp_quote("#ifdef ATL_INITGUID")
cpp_quote("#include <initguid.h>")
cpp_quote("#endif")

[
    object,
    uuid(e21f8a85-b05d-4243-8183-c7cb405588f7),
    pointer_default(unique)
]
interface IRegistrarBase : IUnknown
{
    HRESULT AddReplacement(
        [in] LPCOLESTR Key,
        [in] LPCOLESTR item);

    HRESULT ClearReplacements();
}

[
    object,
    uuid(44EC053B-400F-11D0-9DCD-00A0C90391D3),
    pointer_default(unique)
]
interface IRegistrar : IRegistrarBase
{
    HRESULT ResourceRegisterSz(
        [in] LPCOLESTR resFileName,
        [in] LPCOLESTR szID,
        [in] LPCOLESTR szType);

    HRESULT ResourceUnregisterSz(
        [in] LPCOLESTR resFileName,
        [in] LPCOLESTR szID,
        [in] LPCOLESTR szType);

    HRESULT FileRegister(
        [in] LPCOLESTR fileName);

    HRESULT FileUnregister(
        [in] LPCOLESTR fileName);

    HRESULT StringRegister(
        [in] LPCOLESTR data);

    HRESULT StringUnregister(
        [in] LPCOLESTR data);

    HRESULT ResourceRegister(
        [in] LPCOLESTR resFileName,
        [in] UINT nID,
        [in] LPCOLESTR szType);

    HRESULT ResourceUnregister(
        [in] LPCOLESTR resFileName,
        [in] UINT nID,
        [in] LPCOLESTR szType);
}

[
    object,
    uuid(425b5af0-65f1-11d1-9611-0000f81e0d0d)
]
interface IDocHostUIHandlerDispatch : IDispatch
{
    HRESULT ShowContextMenu([in] DWORD id,
                            [in] LONG x,
                            [in] LONG y,
                            [in] IUnknown *unkreserved,
                            [in] IDispatch *dispreserved,
                            [out, retval] HRESULT *retval);
    HRESULT GetHostInfo([in, out] DWORD *flags,
                        [in, out] DWORD *doubleclick);
    HRESULT ShowUI([in] DWORD id,
                   [in] IUnknown *activeobject,
                   [in] IUnknown *cmdtarget,
                   [in] IUnknown *frame,
                   [in] IUnknown *doc,
                   [out, retval] HRESULT *retval);
    HRESULT HideUI();
    HRESULT UpdateUI();
    HRESULT EnableModeless([in] VARIANT_BOOL enable);
    HRESULT OnDocWindowActivate([in] VARIANT_BOOL activate);
    HRESULT OnFrameWindowActivate([in] VARIANT_BOOL activate);
    HRESULT ResizeBorder([in] LONG left,
                         [in] LONG top,
                         [in] LONG right,
                         [in] LONG bottom,
                         [in] IUnknown *window,
                         [in] VARIANT_BOOL framewindow);
    HRESULT TranslateAccelerator([in] HWND hwnd,
                                 [in] UINT msg,
                                 [in] WPARAM wparam,
                                 [in] LPARAM lparam,
                                 [in] BSTR guid_cmd_group,
                                 [out, retval] HRESULT *retval);
    HRESULT GetOptionKeyPath([out] BSTR *key,
                             [in] DWORD reserved);
    HRESULT GetDropTarget([in] IUnknown *droptarget,
                          [out] IUnknown **ret_droptarget);
    HRESULT GetExternal([out] IDispatch **disp);
    HRESULT TranslateUrl([in] DWORD reserved,
                         [in] BSTR url,
                         [out] BSTR *translated_url);
    HRESULT FilterDataObject([in] IUnknown *dataobject,
                             [out] IUnknown **dataobject_ret);
}

[
    dual,
    object,
    oleautomation,
    uuid(b6ea2051-048a-11d1-82b9-00c04fb9942e)
]
interface IAxWinAmbientDispatch : IDispatch
{
    [propput]
    HRESULT AllowWindowlessActivation([in] VARIANT_BOOL allow);
    [propget]
    HRESULT AllowWindowlessActivation([out, retval] VARIANT_BOOL *allowed);
    [propput, id(-701)]
    HRESULT BackColor([in] OLE_COLOR color);
    [propget, id(-701)]
    HRESULT BackColor([out, retval] OLE_COLOR *color);
    [propput, id(-704)]
    HRESULT ForeColor([in] OLE_COLOR color);
    [propget, id(-704)]
    HRESULT ForeColor([out, retval] OLE_COLOR *color);
    [propput, id(-705)]
    HRESULT LocaleID([in] LCID lcid);
    [propget, id(-705)]
    HRESULT LocaleID([out, retval] LCID *lcid);
    [propput, id(-709)]
    HRESULT UserMode([in] VARIANT_BOOL mode);
    [propget, id(-709)]
    HRESULT UserMode([out, retval] VARIANT_BOOL *mode);
    [propput, id(-713)]
    HRESULT DisplayAsDefault([in] VARIANT_BOOL display);
    [propget, id(-713)]
    HRESULT DisplayAsDefault([out, retval] VARIANT_BOOL *display);
    [propput, id(-703)]
    HRESULT Font([in] IFontDisp *font);
    [propget, id(-703)]
    HRESULT Font([out, retval] IFontDisp **font);
    [propput, id(-706)]
    HRESULT MessageReflect([in] VARIANT_BOOL reflect);
    [propget, id(-706)]
    HRESULT MessageReflect([out, retval] VARIANT_BOOL *reflect);
    [propget, id(-711)]
    HRESULT ShowGrabHandles([out, retval] VARIANT_BOOL *show);
    [propget, id(-712)]
    HRESULT ShowHatching([out, retval] VARIANT_BOOL *show);
    [propput]
    HRESULT DocHostFlags([in] DWORD flags);
    [propget]
    HRESULT DocHostFlags([out, retval] DWORD *flags);
    [propput]
    HRESULT DocHostDoubleClickFlags([in] DWORD flags);
    [propget]
    HRESULT DocHostDoubleClickFlags([out, retval] DWORD *flags);
    [propput]
    HRESULT AllowContextMenu([in] VARIANT_BOOL allow);
    [propget]
    HRESULT AllowContextMenu([out, retval] VARIANT_BOOL *allow);
    [propput]
    HRESULT AllowShowUI([in] VARIANT_BOOL allow);
    [propget]
    HRESULT AllowShowUI([out, retval] VARIANT_BOOL *allow);
    [propput]
    HRESULT OptionKeyPath([in] BSTR path);
    [propget]
    HRESULT OptionKeyPath([out, retval] BSTR *path);
}

[
    dual,
    object,
    oleautomation,
    uuid(b2d0778b-ac99-4c58-a5c8-e7724e5316b5)
]
interface IAxWinAmbientDispatchEx : IAxWinAmbientDispatch
{
    [id(100)]
    HRESULT SetAmbientDispatch([in] IDispatch *disp);
}

cpp_quote("DEFINE_GUID(CLSID_Registrar,0x44ec053a,0x400f,0x11d0,0x9d,0xcd,0x00,0xa0,0xc9,0x03,0x91,0xd3);")

cpp_quote("HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**);")
cpp_quote("HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*);")
cpp_quote("HRESULT WINAPI AtlAxCreateControlLic(LPCOLESTR,HWND,IStream*,IUnknown**,BSTR);")
cpp_quote("HRESULT WINAPI AtlAxCreateControlLicEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*,BSTR);")
cpp_quote("BOOL WINAPI AtlAxWinInit(void);")
cpp_quote("HRESULT WINAPI AtlAxGetControl(HWND,IUnknown**);")
cpp_quote("HRESULT WINAPI AtlAxGetHost(HWND,IUnknown**);")

cpp_quote("HWND WINAPI AtlAxCreateDialogW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);")
cpp_quote("HWND WINAPI AtlAxCreateDialogA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);")
cpp_quote("#define     AtlAxCreateDialog WINELIB_NAME_AW(AtlAxCreateDialog)")
cpp_quote("INT_PTR WINAPI AtlAxDialogBoxW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);")
cpp_quote("INT_PTR WINAPI AtlAxDialogBoxA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);")
cpp_quote("#define        AtlAxDialogBox WINELIB_NAME_AW(AtlAxDialogBox)")
