admin
2020-06-10 a610f2ab6e543d2cb78c1ef212ac6a74ddc067d9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
 
#include "Stdafx.h"
 
#include "ManagedCefBrowserAdapter.h"
#include "WindowInfo.h"
#include "Internals\Messaging\Messages.h"
#include "Internals\CefFrameWrapper.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\Serialization\Primitives.h"
#include "Internals\Serialization\JsObjectsSerialization.h"
 
using namespace CefSharp::Internals::Serialization;
using namespace CefSharp::Internals::Messaging;
 
using namespace CefSharp::Internals::Messaging;
 
bool ManagedCefBrowserAdapter::IsDisposed::get()
{
    return _isDisposed;
}
 
void ManagedCefBrowserAdapter::CreateBrowser(IWindowInfo^ windowInfo, BrowserSettings^ browserSettings, RequestContext^ requestContext, String^ address)
{
    auto cefWindowInfoWrapper = static_cast<WindowInfo^>(windowInfo);
 
    CefString addressNative = StringUtils::ToNative(address);
 
    if (browserSettings == nullptr)
    {
        throw gcnew ArgumentNullException("browserSettings", "cannot be null");
    }
 
    if (browserSettings->IsDisposed)
    {
        throw gcnew ObjectDisposedException("browserSettings", "browser settings has already been disposed. " +
            "BrowserSettings created by CefSharp are automatically disposed, to control the lifecycle create and set your own instance.");
    }
 
    CefRefPtr<CefDictionaryValue> extraInfo = CefDictionaryValue::Create();
    auto legacyBindingEnabled = false;
 
    if (CefSharpSettings::LegacyJavascriptBindingEnabled)
    {
        auto objectRepository = JavascriptObjectRepository;
 
        legacyBindingEnabled = objectRepository->HasBoundObjects;
 
        //For legacy binding we only add values if we have bond objects
        if (legacyBindingEnabled)
        {
            auto listValue = CefListValue::Create();
 
            SerializeJsObjects(objectRepository->GetObjects(nullptr), listValue, 0);
 
            extraInfo->SetList("LegacyBindingObjects", listValue);
        }
    }
 
    extraInfo->SetBool("LegacyBindingEnabled", legacyBindingEnabled);
 
    if (!CefBrowserHost::CreateBrowser(*cefWindowInfoWrapper->GetWindowInfo(), _clientAdapter.get(), addressNative,
        *browserSettings->_browserSettings, extraInfo, static_cast<CefRefPtr<CefRequestContext>>(requestContext)))
    {
        throw gcnew InvalidOperationException("CefBrowserHost::CreateBrowser call failed, review the CEF log file for more details.");
    }
 
    delete windowInfo;
}
 
// NOTE: This was moved out of OnAfterBrowserCreated to prevent the System.ServiceModel assembly from being loaded when WCF is not enabled.
__declspec(noinline) void ManagedCefBrowserAdapter::InitializeBrowserProcessServiceHost(IBrowser^ browser)
{
    _browserProcessServiceHost = gcnew BrowserProcessServiceHost(_javaScriptObjectRepository, Process::GetCurrentProcess()->Id, browser->Identifier, _javascriptCallbackFactory);
    //NOTE: Attempt to solve timing issue where browser is opened and rapidly disposed. In some cases a call to Open throws
    // an exception about the process already being closed. Two relevant issues are #862 and #804.
    if (_browserProcessServiceHost->State == CommunicationState::Created)
    {
        try
        {
            _browserProcessServiceHost->Open();
        }
        catch (Exception^)
        {
            //Ignore exception as it's likely cause when the browser is closing
        }
    }
}
 
// NOTE: This was moved out of ~ManagedCefBrowserAdapter to prevent the System.ServiceModel assembly from being loaded when WCF is not enabled.
__declspec(noinline) void ManagedCefBrowserAdapter::DisposeBrowserProcessServiceHost()
{
    if (_browserProcessServiceHost != nullptr)
    {
        if (CefSharpSettings::WcfTimeout > TimeSpan::Zero)
        {
            _browserProcessServiceHost->Close(CefSharpSettings::WcfTimeout);
        }
        else
        {
            _browserProcessServiceHost->Abort();
        }
        _browserProcessServiceHost = nullptr;
    }
}
 
void ManagedCefBrowserAdapter::OnAfterBrowserCreated(IBrowser^ browser)
{
    if (!_isDisposed)
    {
        _browserWrapper = browser;
        _javascriptCallbackFactory->BrowserAdapter = gcnew WeakReference(this);
 
        //Browser has been initialized, it's now too late to register a sync JSB object if Wcf wasn't enabled
        _javaScriptObjectRepository->IsBrowserInitialized = true;
 
        if (CefSharpSettings::WcfEnabled)
        {
            InitializeBrowserProcessServiceHost(browser);
        }
 
        if (_webBrowserInternal != nullptr)
        {
            _webBrowserInternal->OnAfterBrowserCreated(browser);
        }
    }
}
 
void ManagedCefBrowserAdapter::Resize(int width, int height)
{
    HWND browserHwnd = _clientAdapter->GetBrowserHwnd();
    if (browserHwnd)
    {
        if (width == 0 && height == 0)
        {
            // For windowed browsers when the frame window is minimized set the
            // browser window size to 0x0 to reduce resource usage.
            SetWindowPos(browserHwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
        }
        else
        {
            SetWindowPos(browserHwnd, NULL, 0, 0, width, height, SWP_NOZORDER);
        }
    }
}
 
IBrowser^ ManagedCefBrowserAdapter::GetBrowser(int browserId)
{
    return _clientAdapter->GetBrowserWrapper(browserId);
}
 
IJavascriptCallbackFactory^ ManagedCefBrowserAdapter::JavascriptCallbackFactory::get()
{
    return _javascriptCallbackFactory;
}
 
JavascriptObjectRepository^ ManagedCefBrowserAdapter::JavascriptObjectRepository::get()
{
    return _javaScriptObjectRepository;
}
 
IMethodRunnerQueue^ ManagedCefBrowserAdapter::MethodRunnerQueue::get()
{
    return _methodRunnerQueue;
}
 
void ManagedCefBrowserAdapter::MethodInvocationComplete(Object^ sender, MethodInvocationCompleteArgs^ e)
{
    auto result = e->Result;
    if (result->CallbackId.HasValue)
    {
        _clientAdapter->MethodInvocationComplete(result);
    }
}
 
MCefRefPtr<ClientAdapter> ManagedCefBrowserAdapter::GetClientAdapter()
{
    return _clientAdapter;
}