Files
UnrealEngineUWP/Engine/Source/Runtime/WebBrowser/Public/SWebBrowserView.h

374 lines
13 KiB
C
Raw Normal View History

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340) #lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3209340 on 2016/11/23 by Ben.Marsh Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h. Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms. * Every header now includes everything it needs to compile. * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first. * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h. * Every .cpp file includes its matching .h file first. * This helps validate that each header is including everything it needs to compile. * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more. * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there. * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible. * No engine code explicitly includes a precompiled header any more. * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies. * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files. Tool used to generate this transform is at Engine\Source\Programs\IncludeTool. [CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
#include "CoreMinimal.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Input/PopupMethodReply.h"
#include "Widgets/SWidget.h"
#include "Widgets/SCompoundWidget.h"
#include "Framework/SlateDelegates.h"
#include "Framework/Application/IMenu.h"
#include "Widgets/SViewport.h"
#include "IWebBrowserSingleton.h"
class FWebBrowserViewport;
class IWebBrowserAdapter;
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340) #lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3209340 on 2016/11/23 by Ben.Marsh Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h. Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms. * Every header now includes everything it needs to compile. * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first. * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h. * Every .cpp file includes its matching .h file first. * This helps validate that each header is including everything it needs to compile. * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more. * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there. * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible. * No engine code explicitly includes a precompiled header any more. * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies. * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files. Tool used to generate this transform is at Engine\Source\Programs\IncludeTool. [CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
class IWebBrowserDialog;
class IWebBrowserPopupFeatures;
class IWebBrowserWindow;
struct FWebNavigationRequest;
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340) #lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3209340 on 2016/11/23 by Ben.Marsh Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h. Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms. * Every header now includes everything it needs to compile. * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first. * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h. * Every .cpp file includes its matching .h file first. * This helps validate that each header is including everything it needs to compile. * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more. * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there. * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible. * No engine code explicitly includes a precompiled header any more. * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies. * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files. Tool used to generate this transform is at Engine\Source\Programs\IncludeTool. [CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
enum class EWebBrowserDialogEventResponse;
enum class EWebBrowserDocumentState;
DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnBeforePopupDelegate, FString, FString);
DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnCreateWindowDelegate, const TWeakPtr<IWebBrowserWindow>&, const TWeakPtr<IWebBrowserPopupFeatures>&);
DECLARE_DELEGATE_RetVal_OneParam(bool, FOnCloseWindowDelegate, const TWeakPtr<IWebBrowserWindow>&);
#if WITH_CEF3
typedef SViewport SWebBrowserWidget;
#else
typedef SWidget SWebBrowserWidget;
#endif
class WEBBROWSER_API SWebBrowserView
: public SCompoundWidget
{
public:
DECLARE_DELEGATE_RetVal_TwoParams(bool, FOnBeforeBrowse, const FString& /*Url*/, const FWebNavigationRequest& /*Request*/)
DECLARE_DELEGATE_RetVal_ThreeParams(bool, FOnLoadUrl, const FString& /*Method*/, const FString& /*Url*/, FString& /* Response */)
DECLARE_DELEGATE_RetVal_OneParam(EWebBrowserDialogEventResponse, FOnShowDialog, const TWeakPtr<IWebBrowserDialog>&);
DECLARE_DELEGATE_RetVal(bool, FOnSuppressContextMenu);
SLATE_BEGIN_ARGS(SWebBrowserView)
: _InitialURL(TEXT("https://www.google.com"))
, _ShowErrorMessage(true)
, _SupportsTransparency(false)
, _SupportsThumbMouseButtonNavigation(false)
, _BackgroundColor(255,255,255,255)
, _PopupMenuMethod(TOptional<EPopupMethod>())
, _ContextSettings()
, _ViewportSize(FVector2D::ZeroVector)
{ }
/** A reference to the parent window. */
SLATE_ARGUMENT(TSharedPtr<SWindow>, ParentWindow)
/** URL that the browser will initially navigate to. */
SLATE_ARGUMENT(FString, InitialURL)
/** Optional string to load contents as a web page. */
SLATE_ARGUMENT(TOptional<FString>, ContentsToLoad)
/** Whether to show an error message in case of loading errors. */
SLATE_ARGUMENT(bool, ShowErrorMessage)
/** Should this browser window support transparency. */
SLATE_ARGUMENT(bool, SupportsTransparency)
/** Whether to allow forward and back navigation via the mouse thumb buttons. */
SLATE_ARGUMENT(bool, SupportsThumbMouseButtonNavigation)
/** Opaque background color used before a document is loaded and when no document color is specified. */
SLATE_ARGUMENT(FColor, BackgroundColor)
/** Override the popup menu method used for popup menus. If not set, parent widgets will be queried instead. */
SLATE_ARGUMENT(TOptional<EPopupMethod>, PopupMenuMethod)
/** Override the default global context settings for this specific window. If not set, the global default will be used. */
SLATE_ARGUMENT(TOptional<FBrowserContextSettings>, ContextSettings)
/** Desired size of the web browser viewport. */
SLATE_ATTRIBUTE(FVector2D, ViewportSize);
/** Called when document loading completed. */
SLATE_EVENT(FSimpleDelegate, OnLoadCompleted)
/** Called when document loading failed. */
SLATE_EVENT(FSimpleDelegate, OnLoadError)
/** Called when document loading started. */
SLATE_EVENT(FSimpleDelegate, OnLoadStarted)
/** Called when document title changed. */
SLATE_EVENT(FOnTextChanged, OnTitleChanged)
/** Called when the Url changes. */
SLATE_EVENT(FOnTextChanged, OnUrlChanged)
/** Called before a popup window happens */
SLATE_EVENT(FOnBeforePopupDelegate, OnBeforePopup)
/** Called when the browser requests the creation of a new window */
SLATE_EVENT(FOnCreateWindowDelegate, OnCreateWindow)
/** Called when a browser window close event is detected */
SLATE_EVENT(FOnCloseWindowDelegate, OnCloseWindow)
/** Called before browser navigation. */
SLATE_EVENT(FOnBeforeBrowse, OnBeforeNavigation)
/** Called to allow bypassing page content on load. */
SLATE_EVENT(FOnLoadUrl, OnLoadUrl)
/** Called when the browser needs to show a dialog to the user. */
SLATE_EVENT(FOnShowDialog, OnShowDialog)
/** Called to dismiss any dialogs shown via OnShowDialog. */
SLATE_EVENT(FSimpleDelegate, OnDismissAllDialogs)
SLATE_EVENT(FOnSuppressContextMenu, OnSuppressContextMenu);
SLATE_END_ARGS()
/** Default constructor. */
SWebBrowserView();
~SWebBrowserView();
virtual bool SupportsKeyboardFocus() const override {return true;}
/**
* Construct the widget.
*
* @param InArgs Declaration from which to construct the widget.
*/
void Construct(const FArguments& InArgs, const TSharedPtr<IWebBrowserWindow>& InWebBrowserWindow = nullptr);
/**
* Load the specified URL.
*
* @param NewURL New URL to load.
*/
void LoadURL(FString NewURL);
/**
* Load a string as data to create a web page.
*
* @param Contents String to load.
* @param DummyURL Dummy URL for the page.
*/
void LoadString(FString Contents, FString DummyURL);
/** Reload the current page. */
void Reload();
/** Stop loading the page. */
void StopLoad();
/** Get the current title of the web page. */
FText GetTitleText() const;
/**
* Gets the currently loaded URL.
*
* @return The URL, or empty string if no document is loaded.
*/
FString GetUrl() const;
/**
* Gets the URL that appears in the address bar, this may not be the URL that is currently loaded in the frame.
*
* @return The address bar URL.
*/
FText GetAddressBarUrlText() const;
/** Whether the document finished loading. */
bool IsLoaded() const;
/** Whether the document is currently being loaded. */
bool IsLoading() const;
/** Whether the browser widget is done initializing. */
bool IsInitialized() const;
/** Execute javascript on the current window */
void ExecuteJavascript(const FString& ScriptText);
/**
* Gets the source of the main frame as raw HTML.
*
* This method has to be called asynchronously by passing a callback function, which will be called at a later point when the
* result is ready.
* @param Callback A callable that takes a single string reference for handling the result.
*/
void GetSource(TFunction<void (const FString&)> Callback) const ;
/**
* Expose a UObject instance to the browser runtime.
* Properties and Functions will be accessible from JavaScript side.
* As all communication with the rendering procesis asynchronous, return values (both for properties and function results) are wrapped into JS Future objects.
*
* @param Name The name of the object. The object will show up as window.ue4.{Name} on the javascript side. If there is an existing object of the same name, this object will replace it. If bIsPermanent is false and there is an existing permanent binding, the permanent binding will be restored when the temporary one is removed.
* @param Object The object instance.
* @param bIsPermanent If true, the object will be visible to all pages loaded through this browser widget, otherwise, it will be deleted when navigating away from the current page. Non-permanent bindings should be registered from inside an OnLoadStarted event handler in order to be available before JS code starts loading.
*/
void BindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true);
/**
* Remove an existing script binding registered by BindUObject.
*
* @param Name The name of the object to remove.
* @param Object The object will only be removed if it is the same object as the one passed in.
* @param bIsPermanent Must match the bIsPermanent argument passed to BindUObject.
*/
void UnbindUObject(const FString& Name, UObject* Object, bool bIsPermanent = true);
void BindAdapter(const TSharedRef<IWebBrowserAdapter>& Adapter);
void UnbindAdapter(const TSharedRef<IWebBrowserAdapter>& Adapter);
/** Returns true if the browser can navigate backwards. */
bool CanGoBack() const;
/** Navigate backwards. */
void GoBack();
/** Returns true if the browser can navigate forwards. */
bool CanGoForward() const;
/** Navigate forwards. */
void GoForward();
private:
void SetupParentWindowHandlers();
/** Callback for document loading state changes. */
void HandleBrowserWindowDocumentStateChanged(EWebBrowserDocumentState NewState);
/** Callback to tell slate we want to update the contents of the web view based on changes inside the view. */
void HandleBrowserWindowNeedsRedraw();
/** Callback for document title changes. */
void HandleTitleChanged(FString NewTitle);
/** Callback for loaded url changes. */
void HandleUrlChanged(FString NewUrl);
/** Callback for showing browser tool tips. */
void HandleToolTip(FString ToolTipText);
/**
* A delegate that is executed prior to browser navigation.
*
* @return true if the navigation was handled an no further action should be taken by the browser, false if the browser should handle.
*/
bool HandleBeforeNavigation(const FString& Url, const FWebNavigationRequest& Request);
bool HandleLoadUrl(const FString& Method, const FString& Url, FString& OutResponse);
/**
* A delegate that is executed when the browser requests window creation.
*
* @return true if if the window request was handled, false if the browser requesting the new window should be closed.
*/
bool HandleCreateWindow(const TWeakPtr<IWebBrowserWindow>& NewBrowserWindow, const TWeakPtr<IWebBrowserPopupFeatures>& PopupFeatures);
/**
* A delegate that is executed when closing the browser window.
*
* @return true if if the window close was handled, false otherwise.
*/
bool HandleCloseWindow(const TWeakPtr<IWebBrowserWindow>& BrowserWindow);
/** Callback for showing dialogs to the user */
EWebBrowserDialogEventResponse HandleShowDialog(const TWeakPtr<IWebBrowserDialog>& DialogParams);
/** Callback for dismissing any dialogs previously shown */
void HandleDismissAllDialogs();
/** Callback for popup window permission */
bool HandleBeforePopup(FString URL, FString Target);
/** Callback for showing a popup menu */
void HandleShowPopup(const FIntRect& PopupSize);
/** Callback for hiding the popup menu */
void HandleDismissPopup();
/** Callback from the popup menu notifiying it has been dismissed */
void HandleMenuDismissed(TSharedRef<IMenu>);
virtual FPopupMethodReply OnQueryPopupMethod() const override
{
return PopupMenuMethod.IsSet()
? FPopupMethodReply::UseMethod(PopupMenuMethod.GetValue())
: FPopupMethodReply::Unhandled();
}
void HandleWindowDeactivated();
Copying //UE4/Portal-Staging to //UE4/Dev-Main (Source: //Portal/Main @ 3216504) #lockdown Nick.Penwarden #rb no one ========================== MAJOR FEATURES + CHANGES ========================== Change 3216141 on 2016/11/30 by Justin.Sargent Completed first ready to use pass of the new AutomationDriver module and new Spec test type. Change 3213288 on 2016/11/29 by Leigh.Swift #jira OPP-6353: CEF FName Javascript PROBLEM Removing deprecation of IWebBrowserSingleton::SetJSBindingToLoweringEnabled for now. Change 3212796 on 2016/11/29 by Leigh.Swift #jira OPP-6353: CEF FName Javascript PROBLEM Added SetJSBindingToLoweringEnabled to IWebBrowserSingleton so that the to-lowering of binding names can be disabled. Deprecated SetJSBindingToLoweringEnabled since 4.15. In future the to-lowering will always occurr. Adding GetBindingName helper to FWebJSScripting, which returns a to-lowered name for a UField, unless disabled. Updated all current binding code to use GetBindingName when building from UObjects/UStructs. This affects Windows, Mac, Linux, and Android. Portal currently disables to-lowering unless a commandline -LowercaseJS is provided. Change 3200370 on 2016/11/16 by Richard.Fawcett Ensure we always get the latest version of the user content catalog when promoting marketplace items. Change 3192974 on 2016/11/10 by Leigh.Swift #jira OPP-6365: Crash during shutdown if a manifest is still being downloaded This is because of the OnPreExit core delegate being used to null out the Data uobject member on a manifest, also being the only sensible way to ensure threads complete in a safe and clean manner. Refactoring BuildPatchServices manifest class to not permanently hold any UObject and simply just use one while serialising. This removes the reliance on the OnPreExit delegate from manifest class, making it generally safer behaviour for shutdown. Change 3187028 on 2016/11/04 by Leigh.Swift PortalPublishingTool: Adding UE_Main app to UnrealEngine project Change 3186788 on 2016/11/04 by Richard.Fawcett Change C# wrapper for BuildPatchTool patch generation to prevent clobbering manifest files by default, unless we specifically pass in an optional flag to allow this. #jira OPP-6355 Change 3186779 on 2016/11/04 by Richard.Fawcett Add support to automation tool testing framework for the following assertions: Assert.AreNotEqual(a, b, optionalFailureMessage) Assert.ThrowsError(actionToCarryOut, expectedExceptionType, optionalExceptionMessageContainsString) Moved attribute-based expected exception declarations to their own attribute, TestThrowsExceptionAttribute, which can now accept an optional parameter for a string which should be contained within the exception message. Fixed a bug where a test method with an attribute-based expected exception would not count towards the success total if the exception was encountered as expected. Fixed a bug where NOT throwing an exception when we were expecting one would count as a success. Added an internal property bDoNotLogTestFailsAsError which we can set to true to suppress logging of UAT errors when a test fails (but still count them in our failure results), to allow us to deliberately cause test failures to test the test framework! Added a suite of unit tests for the test framework itself, in TestRunner.Automation.Tests.cs. Change 3185411 on 2016/11/03 by Richard.Fawcett Allow Rocket_PromoteBuild changelist to be overridden by a changelist read from a file. Change 3184843 on 2016/11/03 by Richard.Fawcett Ensure catalog file synced during user content generation is always the latest one. Change 3184752 on 2016/11/03 by Richard.Fawcett Ensure we log reading changelist from specified file. Change 3184744 on 2016/11/03 by Richard.Fawcett Ensure directory is created for Changelist file if it doesn't already exist. Change 3184738 on 2016/11/03 by Richard.Fawcett Ensure we use latest CL from all of Perforce when generating build versions for user content Because of the nature of the build farm, where separate parts of the job are executed on different build agents at different times, this changelist is serialized to the filesystem during execution of a node dedicated to this task, and then made available to all future nodes, so that they're working with a consistent build version. In the case of an execution where we're updating Perforce with new content, this calculation of the changelist occurs AFTER we've updated Perforce with the new content. Have also optimized the build graph scripts to enable Mac and Windows user generated content to execute simultaneously. #jira OPP-6274 Change 3181456 on 2016/11/01 by Andrew.Brown SExpandable area has been modified as the Portal settings mocks weren't able to be achieved with default functionality. Added BodyBorderImage arguement and BodyBorderBackgroundColor attribute so we can specify a different brush/color to use for the expanded area compared with the title area. Additional care was made to ensure that rounded corners still appear correctly if the developer doesn't want to specify a different look to the body. Added AreaTitlePadding attribute, to be able to specify padding between the expand/collapse icon and the header content. Added MinWidth arguement, to ensure that the areas meet a minimum width requirement. Change 3181285 on 2016/11/01 by Richard.Fawcett Ensure user content generated using latest changelist submitted to Perforce, rather than using portal's latest changelist #jira OPP-6274 Change 3177758 on 2016/10/28 by Leigh.Swift #jira OPP-6247: Portal needs Social Plugin integration v1.2 Copying //Portal/Dev-Social to Dev-Main (//Portal/Dev-Main) Change 3175889 on 2016/10/26 by Wes.Fudala Web browser tooltips will no longer continue to appear when the mouse leaves the browser window. #jira: OPP-5895 The Mouseover info in Recent Additions (Marketplace) anchors itself to the mouse pointer over other Browser windows rb: Justin.Sargent Change 3171388 on 2016/10/22 by Leigh.Swift #jira OPP-6343: Launcher crashes patching from 2.12.13 Main to 2.12.13 Release-Live BPS: FBuildPatchAppManifest needs to listen for FCoreDelegates::OnPreExit in order to clean up references to it's UObject which is about to be destroyed. Change 3170373 on 2016/10/21 by Leigh.Swift #jira: OPP-6340: Portal builds fail on audit nodes. Reducing platform regex to only match pre-defined possibilities. [CL 3219291 by Justin Sargent in Main branch]
2016-12-02 13:27:02 -05:00
void HandleWindowActivated();
private:
/** Interface for dealing with a web browser window. */
TSharedPtr<IWebBrowserWindow> BrowserWindow;
/** The slate window that contains this widget. This must be stored weak otherwise we create a circular reference. */
TWeakPtr<SWindow> SlateParentWindowPtr;
/** Viewport interface for rendering the web page. */
TSharedPtr<FWebBrowserViewport> BrowserViewport;
/** Viewport interface for rendering popup menus. */
TSharedPtr<FWebBrowserViewport> MenuViewport;
/** The implementation dependent widget that renders the browser contents. */
TSharedPtr<SWebBrowserWidget> BrowserWidget;
TArray<TSharedRef<IWebBrowserAdapter>> Adapters;
/**
* An interface pointer to a menu object presenting a popup.
* Pointer is null when a popup is not visible.
*/
TWeakPtr<IMenu> PopupMenuPtr;
/** Can be set to override the popup menu method used for popup menus. If not set, parent widgets will be queried instead. */
TOptional<EPopupMethod> PopupMenuMethod;
/** The url that appears in the address bar which can differ from the url of the loaded page */
FText AddressBarUrl;
/** A delegate that is invoked when document loading completed. */
FSimpleDelegate OnLoadCompleted;
/** A delegate that is invoked when document loading failed. */
FSimpleDelegate OnLoadError;
/** A delegate that is invoked when document loading started. */
FSimpleDelegate OnLoadStarted;
/** A delegate that is invoked when document title changed. */
FOnTextChanged OnTitleChanged;
/** A delegate that is invoked when document address changed. */
FOnTextChanged OnUrlChanged;
/** A delegate that is invoked when the browser attempts to pop up a new window */
FOnBeforePopupDelegate OnBeforePopup;
/** A delegate that is invoked when the browser requests a UI window for another browser it spawned */
FOnCreateWindowDelegate OnCreateWindow;
/** A delegate that is invoked when a window close event is detected */
FOnCloseWindowDelegate OnCloseWindow;
/** A delegate that is invoked prior to browser navigation */
FOnBeforeBrowse OnBeforeNavigation;
/** A delegate that is invoked when loading a resource, allowing the application to provide contents directly */
FOnLoadUrl OnLoadUrl;
/** A delegate that is invoked when when the browser needs to present a dialog to the user */
FOnShowDialog OnShowDialog;
/** A delegate that is invoked when when the browser needs to dismiss all dialogs */
FSimpleDelegate OnDismissAllDialogs;
FDelegateHandle SlateParentWindowSetupTickHandle;
FOnSuppressContextMenu OnSuppressContextMenu;
protected:
bool HandleSuppressContextMenu();
};