You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
506 lines
16 KiB
506 lines
16 KiB
//+------------------------------------------------------------------
|
|
//
|
|
// Microsoft IEPEERS
|
|
// Copyright (C) Microsoft Corporation, 1999.
|
|
//
|
|
// File: iextags\select.hxx
|
|
//
|
|
// Contents: The SELECT control.
|
|
//
|
|
// Classes: CIESelectElement
|
|
//
|
|
// Interfaces: IHTMLSelectElement3
|
|
// IPrivateSelect
|
|
//
|
|
//-------------------------------------------------------------------
|
|
|
|
#ifndef __SELECT_HXX_
|
|
#define __SELECT_HXX_
|
|
|
|
#include "basectl.hxx"
|
|
#include "resource.h" // main symbols
|
|
|
|
// Uncomment this line to turn on the new GetSize features
|
|
#define SELECT_GETSIZE
|
|
#define SELECT_TIMERVL
|
|
|
|
//
|
|
// These are properties and flavors for the control.
|
|
// The numbers are setup so that we only need one flavor bitfield.
|
|
// The flavor will be equal something from the flavor enumeration.
|
|
// The flavor can be "&"ed with a property to determine if that
|
|
// property is active. This allows us to minimize the book-keeping
|
|
// on the flavor bitfield.
|
|
//
|
|
enum // Properties
|
|
{
|
|
SELECT_DROPBOX = 1,
|
|
SELECT_MULTIPLE = 2,
|
|
SELECT_INPOPUP = 4,
|
|
};
|
|
|
|
#define SELECT_ISLISTBOX(flag) (!(flag & SELECT_DROPBOX))
|
|
#define SELECT_ISDROPBOX(flag) (flag & SELECT_DROPBOX)
|
|
#define SELECT_ISMULTIPLE(flag) (flag & SELECT_MULTIPLE)
|
|
#define SELECT_ISINPOPUP(flag) (flag & SELECT_INPOPUP)
|
|
|
|
enum
|
|
{
|
|
SELECT_SHIFT = 1,
|
|
SELECT_CTRL = 2,
|
|
SELECT_ALT = 4,
|
|
SELECT_CLEARPREV = 8,
|
|
SELECT_EXTEND = 16,
|
|
SELECT_TOGGLE = 32,
|
|
SELECT_FIREEVENT = 64,
|
|
};
|
|
|
|
enum
|
|
{
|
|
SELECTES_POPUP = 1,
|
|
SELECTES_VIEWLINK = 2,
|
|
SELECTES_BUTTON = 4,
|
|
SELECTES_INPOPUP = 8,
|
|
};
|
|
|
|
interface IPrivateOption;
|
|
typedef interface IPrivateOption IPrivateOption;
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IPrivateSelect
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/* {3050f6a2-98b5-11cf-bb82-00aa00bdce0b} */
|
|
DEFINE_GUID(IID_IPrivateSelect,
|
|
0x3050f6a2, 0x98b5, 0x11cf, 0xbb, 0x82, 0x0, 0xaa, 0x0, 0xbd, 0xce, 0x0b);
|
|
|
|
interface IPrivateSelect : public IUnknown
|
|
{
|
|
STDMETHOD(OnOptionClicked)(long lIndex, DWORD dwFlags) PURE;
|
|
STDMETHOD(OnOptionSelected)(VARIANT_BOOL bSelected, long lIndex, DWORD dwFlags) PURE;
|
|
STDMETHOD(OnOptionHighlighted)(long lIndex) PURE;
|
|
STDMETHOD(OnOptionFocus)(long lIndex, VARIANT_BOOL bRequireRefresh = VARIANT_TRUE) PURE;
|
|
STDMETHOD(InitOptions)() PURE;
|
|
#ifdef SELECT_GETSIZE
|
|
STDMETHOD(OnOptionSized)(SIZE* psizeOption, BOOL bNew, BOOL bAdjust) PURE;
|
|
#else
|
|
STDMETHOD(SetDimensions)() PURE;
|
|
#endif
|
|
STDMETHOD(GetDisabled)(VARIANT_BOOL *pbDisabled) PURE;
|
|
STDMETHOD(GetSelectedIndex)(long *plIndex) PURE;
|
|
STDMETHOD(SelectCurrentOption)(DWORD dwFlags) PURE;
|
|
STDMETHOD(MoveFocusByOne)(BOOL bUp, DWORD dwFlags) PURE;
|
|
STDMETHOD(SetInPopup)(IHTMLPopup *pPopup) PURE;
|
|
STDMETHOD(CommitSelection)(BOOL *pbChanged) PURE;
|
|
STDMETHOD(SetWritingMode)(BSTR bstrName) PURE;
|
|
|
|
STDMETHOD(GetFlavor)(DWORD *pdwFlavor)
|
|
{
|
|
Assert(pdwFlavor);
|
|
*pdwFlavor = _fFlavor;
|
|
return S_OK;
|
|
}
|
|
|
|
unsigned _fFlavor:5;
|
|
};
|
|
|
|
typedef interface IPrivateSelect IPrivateSelect;
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CIESelectElement
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
class ATL_NO_VTABLE CIESelectElement :
|
|
public CBaseCtl,
|
|
public CComCoClass<CIESelectElement, &CLSID_CIESelectElement>,
|
|
public IDispatchImpl<IHTMLSelectElement3, &IID_IHTMLSelectElement3, &LIBID_IEXTagLib>,
|
|
public IElementBehaviorSubmit,
|
|
public IElementBehaviorFocus,
|
|
#ifdef SELECT_GETSIZE
|
|
public IElementBehaviorLayout,
|
|
#endif
|
|
protected IPrivateSelect
|
|
{
|
|
friend class CIEOptionElement;
|
|
|
|
private:
|
|
class CEventSink;
|
|
friend class CIESelectElement::CEventSink;
|
|
|
|
public:
|
|
|
|
CIESelectElement();
|
|
~CIESelectElement();
|
|
|
|
//
|
|
// IElementBehavior overrides
|
|
//
|
|
STDMETHOD(Detach)();
|
|
|
|
//
|
|
// IElementBehaviorSubmit overrides
|
|
//
|
|
STDMETHOD(Reset)();
|
|
STDMETHOD(GetSubmitInfo)(IHTMLSubmitData * pSubmitData);
|
|
|
|
//
|
|
// IElementBehaviorFocus overrides
|
|
//
|
|
STDMETHOD(GetFocusRect)(RECT * pRect);
|
|
|
|
#ifdef SELECT_GETSIZE
|
|
//
|
|
// IElementBehaviorLayout
|
|
//
|
|
STDMETHOD(GetLayoutInfo)(LONG *plLayoutInfo);
|
|
STDMETHOD(GetSize)(LONG dwFlags,
|
|
SIZE sizeContent,
|
|
POINT * pptTranslate,
|
|
POINT *pptTopLeft,
|
|
SIZE *psizeProposed);
|
|
STDMETHOD(GetPosition)(LONG lFlags, POINT * ppt) { return E_NOTIMPL; };
|
|
STDMETHOD(MapSize)(SIZE *psizeIn, RECT *prcOut) { return E_NOTIMPL; };
|
|
|
|
#endif
|
|
|
|
//
|
|
// CBaseCtl overrides
|
|
//
|
|
virtual HRESULT Init();
|
|
|
|
//
|
|
// CBaseCtl Event Methods
|
|
//
|
|
virtual HRESULT OnContentReady();
|
|
virtual HRESULT OnFocus(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnBlur(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnMouseDown(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnMouseUp(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnMouseOver(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnMouseOut(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnMouseMove(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnKeyDown(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnSelectStart(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnScroll(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnContextMenu(CEventObjectAccess *pEvent);
|
|
virtual HRESULT OnPropertyChange(CEventObjectAccess *pEvent, BSTR bstr);
|
|
|
|
//
|
|
// IHTMLSelectElement3 overrides
|
|
//
|
|
STDMETHOD(put_name)(BSTR bstrName);
|
|
STDMETHOD(get_name)(BSTR *pbstrName);
|
|
STDMETHOD(put_size)(long lSize);
|
|
STDMETHOD(get_size)(long *plSize);
|
|
STDMETHOD(put_selectedIndex)(long lIndex);
|
|
STDMETHOD(get_selectedIndex)(long *plIndex);
|
|
STDMETHOD(put_multiple)(VARIANT_BOOL bMultiple);
|
|
STDMETHOD(get_multiple)(VARIANT_BOOL *bMultiple);
|
|
STDMETHOD(clearSelection)();
|
|
STDMETHOD(selectAll)();
|
|
STDMETHOD(add)(IDispatch *pElement, VARIANT varIndex);
|
|
STDMETHOD(remove)(long lIndex);
|
|
STDMETHOD(get_length)(long *plLength);
|
|
STDMETHOD(get_type)(BSTR *pbstrType);
|
|
STDMETHOD(get_options)(IDispatch ** ppOptions);
|
|
STDMETHOD(get__newEnum)(IUnknown ** p);
|
|
STDMETHOD(item)(VARIANT name, VARIANT index, IDispatch ** pdisp);
|
|
STDMETHOD(tags)(VARIANT tagName, IDispatch ** pdisp);
|
|
STDMETHOD(urns)(VARIANT urn, IDispatch ** pdisp);
|
|
|
|
//
|
|
// Wiring
|
|
//
|
|
DECLARE_REGISTRY_RESOURCEID(IDR_SELECT)
|
|
DECLARE_NOT_AGGREGATABLE(CIESelectElement)
|
|
|
|
BEGIN_COM_MAP(CIESelectElement)
|
|
COM_INTERFACE_ENTRY2(IDispatch,IHTMLSelectElement3)
|
|
COM_INTERFACE_ENTRY(IAccessible)
|
|
COM_INTERFACE_ENTRY(IElementBehavior)
|
|
COM_INTERFACE_ENTRY(IElementBehaviorSubmit)
|
|
COM_INTERFACE_ENTRY(IElementBehaviorFocus)
|
|
#ifdef SELECT_GETSIZE
|
|
COM_INTERFACE_ENTRY(IElementBehaviorLayout)
|
|
#endif
|
|
COM_INTERFACE_ENTRY(IPersistPropertyBag2)
|
|
COM_INTERFACE_ENTRY(IHTMLSelectElement3)
|
|
COM_INTERFACE_ENTRY(IPrivateSelect)
|
|
END_COM_MAP()
|
|
|
|
private:
|
|
//
|
|
// IElementBehaviorSubmit Helpers
|
|
//
|
|
HRESULT GetSingleSubmitInfo(IHTMLSubmitData *pSubmitData, CComBSTR bstrName);
|
|
HRESULT GetMultipleSubmitInfo(IHTMLSubmitData *pSubmitData, CComBSTR bstrName);
|
|
|
|
//
|
|
// IElementBehaviorFocus Helpers
|
|
//
|
|
HRESULT RefreshFocusRect();
|
|
|
|
//
|
|
// CBaseCtl Helpers
|
|
//
|
|
HRESULT SetupDefaultStyle();
|
|
HRESULT MakeVisible(BOOL bShow = TRUE);
|
|
HRESULT InitContent();
|
|
HRESULT StartDrag();
|
|
HRESULT FinishDrag();
|
|
HRESULT HandleDownXY(POINT pt, BOOL bCtrlKey);
|
|
HRESULT GetOptionIndexFromY(long lY, long *plIndex, BOOL *pbNeedTimer);
|
|
HRESULT SelectByKey(long lKey);
|
|
HRESULT SearchForKey(long lKey, long lStart, long lEnd, long *plIndex);
|
|
HRESULT CancelEvent(CEventObjectAccess *pEvent);
|
|
|
|
HRESULT OnButtonMouseDown(CEventObjectAccess *pEvent);
|
|
HRESULT PressButton(BOOL bDown);
|
|
|
|
#ifdef SELECT_GETSIZE
|
|
HRESULT IsWidthHeightSet(BOOL *pbWidthSet, BOOL *pbHeightSet);
|
|
HRESULT BecomeDropBox();
|
|
HRESULT BecomeListBox();
|
|
HRESULT RefreshListBox();
|
|
#else
|
|
HRESULT SetDimensions(long lSize);
|
|
#endif
|
|
HRESULT SetAllSelected(VARIANT_BOOL bSelected, DWORD dwFlags);
|
|
HRESULT GetNumOptions(long *plItems);
|
|
HRESULT GetIndex(long lIndex, IHTMLOptionElement2 **ppOption);
|
|
HRESULT GetIndex(long lIndex, IPrivateOption **ppOption);
|
|
HRESULT GetIndex(long lIndex, IHTMLElement **ppElem);
|
|
HRESULT GetIndex(long lIndex, IDispatch **ppOption);
|
|
HRESULT SelectRange(long lAnchor, long lLast, long lNew);
|
|
|
|
HRESULT AddOptionHelper(IHTMLOptionElement2 *pOption, long lIndex);
|
|
HRESULT RemoveOptionHelper(long lIndex);
|
|
HRESULT ResetIndexes();
|
|
HRESULT ParseChildren();
|
|
|
|
HRESULT GetScrollTopBottom(long *plScrollTop, long *plScrollBottom);
|
|
HRESULT PushFocusToExtreme(BOOL bTop);
|
|
HRESULT MakeOptionVisible(IPrivateOption *pOption);
|
|
HRESULT SelectVisibleIndex(long lIndex);
|
|
HRESULT GetTopVisibleOptionIndex(long *plIndex);
|
|
HRESULT GetBottomVisibleOptionIndex(long *plIndex);
|
|
HRESULT GetFirstSelected(long *plIndex);
|
|
HRESULT Select(long lIndex);
|
|
|
|
HRESULT CommitSingleSelection(BOOL *pbChanged);
|
|
HRESULT CommitMultipleSelection(BOOL *pbChanged);
|
|
HRESULT FireOnChange();
|
|
void AdjustChangedRange(long lIndex);
|
|
|
|
//
|
|
// DropBox Helpers
|
|
//
|
|
HRESULT SetupDropBox();
|
|
HRESULT SetupDropControl();
|
|
#ifdef SELECT_GETSIZE
|
|
HRESULT InitViewLink();
|
|
HRESULT DeInitViewLink();
|
|
HRESULT EngageViewLink();
|
|
HRESULT SetupButton(IHTMLElement *pButton);
|
|
HRESULT SetupDisplay(IHTMLElement *pDisplay);
|
|
HRESULT SetupDropControlDimensions();
|
|
#endif
|
|
HRESULT SetupPopup();
|
|
HRESULT UpdatePopup();
|
|
HRESULT SetDisplayHighlight(BOOL bOn);
|
|
HRESULT ShowPopup();
|
|
HRESULT HidePopup();
|
|
HRESULT TogglePopup();
|
|
HRESULT AttachEventToSink(IHTMLElement2 *pElem, CComBSTR& bstr, CEventSink* pSink);
|
|
HRESULT AttachEventToSink(IHTMLDocument3 *pDoc, CComBSTR& bstr, CEventSink* pSink);
|
|
HRESULT DropDownSelect(IPrivateOption *pOption);
|
|
HRESULT SynchSelWithPopup();
|
|
HRESULT RefreshView();
|
|
HRESULT SetPixelHeightWidth();
|
|
HRESULT SetWritingModeFlag();
|
|
//
|
|
// ListBox Helpers
|
|
//
|
|
HRESULT SetupListBox();
|
|
|
|
//
|
|
// IPrivateSelect overrides
|
|
//
|
|
STDMETHOD(OnOptionClicked)(long lIndex, DWORD dwFlags);
|
|
STDMETHOD(OnOptionSelected)(VARIANT_BOOL bSelected, long lIndex, DWORD dwFlags);
|
|
STDMETHOD(OnOptionHighlighted)(long lIndex);
|
|
STDMETHOD(OnOptionFocus)(long lIndex, VARIANT_BOOL bRequireRefresh = VARIANT_TRUE);
|
|
STDMETHOD(InitOptions)();
|
|
STDMETHOD(GetSelectedIndex)(long *plIndex);
|
|
STDMETHOD(GetDisabled)(VARIANT_BOOL *pbDisabled);
|
|
#ifdef SELECT_GETSIZE
|
|
STDMETHOD(OnOptionSized)(SIZE* psizeOption, BOOL bNew, BOOL bAdjust);
|
|
VOID AdjustSizeForScrollbar(SIZE *pSize);
|
|
#else
|
|
STDMETHOD(SetDimensions)();
|
|
#endif
|
|
STDMETHOD(MoveFocusByOne)(BOOL bUp, DWORD dwFlags);
|
|
STDMETHOD(SelectCurrentOption)(DWORD dwFlags);
|
|
STDMETHOD(CommitSelection)(BOOL *pbChanged);
|
|
STDMETHOD(SetWritingMode)(BSTR bstrName);
|
|
|
|
STDMETHOD(SetInPopup)(IHTMLPopup *pPopup)
|
|
{
|
|
_fFlavor |= SELECT_INPOPUP;
|
|
_pPopup = pPopup;
|
|
return S_OK;
|
|
};
|
|
|
|
//
|
|
// Called by the event sink
|
|
//
|
|
HRESULT OnChangeInPopup();
|
|
|
|
//
|
|
// Attributes
|
|
//
|
|
private:
|
|
|
|
long _lFocusIndex;
|
|
IPrivateOption *_pLastSelected;
|
|
IPrivateOption *_pLastHighlight;
|
|
long _lShiftAnchor;
|
|
|
|
//
|
|
// _lMaxHeight is for all the places where we
|
|
// assume we have fixed height options (all options
|
|
// are the same height).
|
|
//
|
|
// When we want to support different height options,
|
|
// then we need to change each location where
|
|
// this is used.
|
|
//
|
|
long _lMaxHeight;
|
|
|
|
IHTMLPopup *_pPopup;
|
|
VARIANT_BOOL _bPopupOpen;
|
|
|
|
CEventSink *_pSinkPopup;
|
|
CEventSink *_pSinkVL;
|
|
CEventSink *_pSinkButton;
|
|
|
|
IHTMLElement *_pElemDisplay;
|
|
IDispatch *_pDispDocLink;
|
|
|
|
IHTMLStyle *_pStyleButton;
|
|
IPrivateSelect *_pSelectInPopup;
|
|
|
|
unsigned _fDragMode:1;
|
|
unsigned _fButtonHit:1;
|
|
|
|
#ifdef SELECT_GETSIZE
|
|
unsigned _fLayoutDirty:1;
|
|
unsigned _fContentReady:1;
|
|
unsigned _fAllOptionsSized:1;
|
|
unsigned _fVLEngaged:1;
|
|
unsigned _fNeedScrollBar:1;
|
|
|
|
SIZE _sizeSelect;
|
|
SIZE _sizeContent;
|
|
SIZE _sizeOption;
|
|
// We need _sizeOptionReported since _sizeOption can get overwritten in GetSize
|
|
SIZE _sizeOptionReported;
|
|
long _lNumOptionsReported;
|
|
#else
|
|
SIZE _lPopupSize;
|
|
#endif
|
|
|
|
long _lOnChangeCookie;
|
|
long _lOnMouseDownCookie;
|
|
long _lOnMouseUpCookie;
|
|
long _lOnClickCookie;
|
|
long _lOnKeyDownCookie;
|
|
long _lOnKeyUpCookie;
|
|
long _lOnKeyPressedCookie;
|
|
|
|
long _fWritingModeTBRL;
|
|
long _lTopChanged;
|
|
long _lBottomChanged;
|
|
|
|
//
|
|
// Timer related
|
|
//
|
|
HRESULT SetScrollTimeout(POINT pt, BOOL bCtrl);
|
|
HRESULT ClearScrollTimeout();
|
|
static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
|
static CIESelectElement *_pTimerSelect;
|
|
static UINT_PTR _iTimerID;
|
|
static POINT _ptSavedPoint;
|
|
static BOOL _bSavedCtrl;
|
|
|
|
#ifdef SELECT_TIMERVL
|
|
static VOID InitTimerVLServices();
|
|
static VOID DeInitTimerVLServices();
|
|
static VOID SetTimerVL();
|
|
static VOID ClearTimerVL();
|
|
static VOID AddSelectToTimerVLQueue(CIESelectElement *pSelect);
|
|
static VOID CALLBACK TimerVLProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
|
|
|
|
struct SELECT_TIMERVL_LINKELEM
|
|
{
|
|
CIESelectElement *pSelect;
|
|
struct SELECT_TIMERVL_LINKELEM *pNext;
|
|
};
|
|
|
|
static UINT_PTR _iTimerVL;
|
|
static LONG _lTimerVLRef;
|
|
static CRITICAL_SECTION _lockTimerVL;
|
|
static struct SELECT_TIMERVL_LINKELEM *_queueTimerVL;
|
|
#endif
|
|
|
|
public:
|
|
DECLARE_PROPDESC_MEMBERS(6);
|
|
|
|
private:
|
|
class CEventSink : public IDispatch
|
|
{
|
|
public:
|
|
CEventSink (CIESelectElement *pParent, DWORD dwFlags);
|
|
|
|
//
|
|
// IUnknown
|
|
//
|
|
STDMETHODIMP QueryInterface(REFIID, void **);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
//
|
|
// IDispatch
|
|
//
|
|
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
|
|
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo);
|
|
STDMETHODIMP GetIDsOfNames( REFIID riid,
|
|
LPOLESTR *rgszNames,
|
|
UINT cNames,
|
|
LCID lcid,
|
|
DISPID *rgDispId);
|
|
STDMETHODIMP Invoke(DISPID dispIdMember,
|
|
REFIID riid,
|
|
LCID lcid,
|
|
WORD wFlags,
|
|
DISPPARAMS *pDispParams,
|
|
VARIANT *pVarResult,
|
|
EXCEPINFO *pExcepInfo,
|
|
UINT *puArgErr);
|
|
private:
|
|
CIESelectElement *_pParent;
|
|
DWORD _dwFlags;
|
|
};
|
|
|
|
};
|
|
|
|
|
|
#endif // __SELECT_HXX_
|