Browse Source

tags/2021-05-28
jules 17 years ago
parent
commit
0108b2f1d2
9 changed files with 1100 additions and 0 deletions
  1. +6
    -0
      build/linux/JUCE.make
  2. +135
    -0
      build/linux/platform_specific_code/juce_linux_WebBrowserComponent.cpp
  3. +8
    -0
      build/macosx/Juce.xcodeproj/project.pbxproj
  4. +442
    -0
      build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm
  5. +362
    -0
      build/win32/platform_specific_code/juce_win32_WebBrowserComponent.cpp
  6. +8
    -0
      build/win32/vc8/JUCE.vcproj
  7. +1
    -0
      docs/JUCE changelist.txt
  8. +3
    -0
      src/juce_app_includes.h
  9. +135
    -0
      src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h

+ 6
- 0
build/linux/JUCE.make View File

@@ -411,6 +411,7 @@ OBJECTS := \
$(OBJDIR)/juce_linux_Network.o \
$(OBJDIR)/juce_linux_SystemStats.o \
$(OBJDIR)/juce_linux_Threads.o \
$(OBJDIR)/juce_linux_WebBrowserComponent.o \
$(OBJDIR)/juce_linux_Windowing.o \

MKDIR_TYPE := msdos
@@ -2327,6 +2328,11 @@ $(OBJDIR)/juce_linux_Threads.o: platform_specific_code/juce_linux_Threads.cpp
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_linux_WebBrowserComponent.o: platform_specific_code/juce_linux_WebBrowserComponent.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o $@ -c $<

$(OBJDIR)/juce_linux_Windowing.o: platform_specific_code/juce_linux_Windowing.cpp
-@$(CMD_MKOBJDIR)
@echo $(notdir $<)


+ 135
- 0
build/linux/platform_specific_code/juce_linux_WebBrowserComponent.cpp View File

@@ -0,0 +1,135 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
/*
Sorry.. This class isn't implemented on Linux!
*/
//==============================================================================
WebBrowserComponent::WebBrowserComponent()
: browser (0),
blankPageShown (false)
{
setOpaque (true);
}
WebBrowserComponent::~WebBrowserComponent()
{
}
//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
lastHeaders.clear();
if (headers != 0)
lastHeaders = *headers;
lastPostData.setSize (0);
if (postData != 0)
lastPostData = *postData;
blankPageShown = false;
}
void WebBrowserComponent::stop()
{
}
void WebBrowserComponent::goBack()
{
lastURL = String::empty;
blankPageShown = false;
}
void WebBrowserComponent::goForward()
{
lastURL = String::empty;
}
//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
g.fillAll (Colours::white);
}
void WebBrowserComponent::checkWindowAssociation()
{
}
void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL = String::empty;
}
}
void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::moved()
{
}
void WebBrowserComponent::resized()
{
}
void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}
bool WebBrowserComponent::pageAboutToLoad (const String& url)
{
return true;
}
END_JUCE_NAMESPACE

+ 8
- 0
build/macosx/Juce.xcodeproj/project.pbxproj View File

@@ -208,6 +208,8 @@
847F72DC0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */; };
847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */; };
847F72DE0C2702A000CBECEC /* juce_FileTreeComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 847F72DA0C2702A000CBECEC /* juce_FileTreeComponent.h */; };
848A560B0DDDD3E40041C706 /* juce_mac_WebBrowserComponent.mm in Sources */ = {isa = PBXBuildFile; fileRef = 848A560A0DDDD3E40041C706 /* juce_mac_WebBrowserComponent.mm */; };
848A560E0DDDD3FB0041C706 /* juce_WebBrowserComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A560D0DDDD3FB0041C706 /* juce_WebBrowserComponent.h */; };
8495BB8C0D8067B2001D9C0B /* juce_AudioThumbnail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8495BB880D8067B2001D9C0B /* juce_AudioThumbnail.cpp */; };
8495BB8D0D8067B2001D9C0B /* juce_AudioThumbnail.h in Headers */ = {isa = PBXBuildFile; fileRef = 8495BB890D8067B2001D9C0B /* juce_AudioThumbnail.h */; };
8495BB8E0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8495BB8A0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp */; };
@@ -897,6 +899,8 @@
847F72D80C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_DirectoryContentsDisplayComponent.h; path = filebrowser/juce_DirectoryContentsDisplayComponent.h; sourceTree = "<group>"; };
847F72D90C2702A000CBECEC /* juce_FileTreeComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_FileTreeComponent.cpp; path = filebrowser/juce_FileTreeComponent.cpp; sourceTree = "<group>"; };
847F72DA0C2702A000CBECEC /* juce_FileTreeComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_FileTreeComponent.h; path = filebrowser/juce_FileTreeComponent.h; sourceTree = "<group>"; };
848A560A0DDDD3E40041C706 /* juce_mac_WebBrowserComponent.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_WebBrowserComponent.mm; sourceTree = "<group>"; };
848A560D0DDDD3FB0041C706 /* juce_WebBrowserComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_WebBrowserComponent.h; sourceTree = "<group>"; };
8495BB880D8067B2001D9C0B /* juce_AudioThumbnail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioThumbnail.cpp; sourceTree = "<group>"; };
8495BB890D8067B2001D9C0B /* juce_AudioThumbnail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_AudioThumbnail.h; sourceTree = "<group>"; };
8495BB8A0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_AudioThumbnailCache.cpp; sourceTree = "<group>"; };
@@ -1554,6 +1558,7 @@
847D06460DD88D1100DF6A61 /* juce_mac_Network.mm */,
84A4882508A22E2400752A2B /* juce_mac_SystemStats.cpp */,
84A4882608A22E2400752A2B /* juce_mac_Threads.cpp */,
848A560A0DDDD3E40041C706 /* juce_mac_WebBrowserComponent.mm */,
84A4882708A22E2400752A2B /* juce_mac_Windowing.cpp */,
);
name = "mac specific code";
@@ -1937,6 +1942,7 @@
84A488EB08A22E4900752A2B /* juce_PreferencesPanel.h */,
84A488EC08A22E4900752A2B /* juce_QuickTimeMovieComponent.cpp */,
84A488ED08A22E4900752A2B /* juce_QuickTimeMovieComponent.h */,
848A560D0DDDD3FB0041C706 /* juce_WebBrowserComponent.h */,
);
name = special;
path = ../../src/juce_appframework/gui/components/special;
@@ -2904,6 +2910,7 @@
8495BB960D806BDA001D9C0B /* juce_InputSource.h in Headers */,
84581EEB0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.h in Headers */,
84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */,
848A560E0DDDD3FB0041C706 /* juce_WebBrowserComponent.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3320,6 +3327,7 @@
84581EEA0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.cpp in Sources */,
84CE8A410DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm in Sources */,
847D06470DD88D1100DF6A61 /* juce_mac_Network.mm in Sources */,
848A560B0DDDD3E40041C706 /* juce_mac_WebBrowserComponent.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 442
- 0
build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm View File

@@ -0,0 +1,442 @@
/*
==============================================================================

This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.

------------------------------------------------------------------------------

JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

JUCE 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA

------------------------------------------------------------------------------

If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.

==============================================================================
*/

#include "../../../src/juce_core/basics/juce_StandardHeader.h"

#import <Cocoa/Cocoa.h>
#import <WebKit/HIWebView.h>
#import <WebKit/WebPolicyDelegate.h>
#import <WebKit/CarbonUtils.h>

BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/events/juce_Timer.h"
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
END_JUCE_NAMESPACE

//==============================================================================
@interface DownloadClickDetector : NSObject
{
juce::WebBrowserComponent* ownerComponent;
}

- (DownloadClickDetector*) init: (juce::WebBrowserComponent*) ownerComponent;

- (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation
request: (NSURLRequest*) request
frame: (WebFrame*) frame
decisionListener: (id<WebPolicyDecisionListener>) listener;
@end

//==============================================================================
@implementation DownloadClickDetector

- (DownloadClickDetector*) init: (juce::WebBrowserComponent*) ownerComponent_
{
[super init];
ownerComponent = ownerComponent_;
return self;
}

- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener
{
NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];

if (ownerComponent->pageAboutToLoad (juce::String::fromUTF8 ((const juce::uint8*) [[url absoluteString] UTF8String])))
[listener use];
else
[listener ignore];
}

@end

BEGIN_JUCE_NAMESPACE

//==============================================================================
class WebBrowserComponentInternal : public Timer
{
public:
WebBrowserComponentInternal (WebBrowserComponent* const owner_)
: owner (owner_),
view (0),
webView (0)
{
HIWebViewCreate (&view);

ComponentPeer* const peer = owner_->getPeer();
jassert (peer != 0);

if (view != 0 && peer != 0)
{
WindowRef parentWindow = (WindowRef) peer->getNativeHandle();

WindowAttributes attributes;
GetWindowAttributes (parentWindow, &attributes);

HIViewRef parentView = 0;

if ((attributes & kWindowCompositingAttribute) != 0)
{
HIViewRef root = HIViewGetRoot (parentWindow);
HIViewFindByID (root, kHIViewWindowContentID, &parentView);

if (parentView == 0)
parentView = root;
}
else
{
GetRootControl (parentWindow, (ControlRef*) &parentView);

if (parentView == 0)
CreateRootControl (parentWindow, (ControlRef*) &parentView);
}

HIViewAddSubview (parentView, view);
updateBounds();
show();

webView = HIWebViewGetWebView (view);

clickListener = [[DownloadClickDetector alloc] init: owner_];
[webView setPolicyDelegate: clickListener];
}

startTimer (500);
}

~WebBrowserComponentInternal()
{
[webView setPolicyDelegate: nil];
[clickListener release];

if (view != 0)
CFRelease (view);
}

// Horrific bodge-workaround for the fact that the webview somehow hangs onto key
// focus when you pop up a new window, no matter what that window does to
// try to grab focus for itself. This catches such a situation and forces
// focus away from the webview, then back to the place it should be..
void timerCallback()
{
WindowRef viewWindow = HIViewGetWindow (view);
WindowRef focusedWindow = GetUserFocusWindow();

if (focusedWindow != viewWindow)
{
if (HIViewSubtreeContainsFocus (view))
{
HIViewAdvanceFocus (HIViewGetRoot (viewWindow), 0);
HIViewAdvanceFocus (HIViewGetRoot (focusedWindow), 0);
}
}
}

void show()
{
HIViewSetVisible (view, true);
}

void hide()
{
HIViewSetVisible (view, false);
}

void goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
char** headerNamesAsChars = 0;
char** headerValuesAsChars = 0;
int numHeaders = 0;

if (headers != 0)
{
numHeaders = headers->size();

headerNamesAsChars = (char**) juce_malloc (sizeof (char*) * numHeaders);
headerValuesAsChars = (char**) juce_malloc (sizeof (char*) * numHeaders);

int i;
for (i = 0; i < numHeaders; ++i)
{
const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
headerNamesAsChars[i] = (char*) juce_calloc (headerName.copyToUTF8 (0));
headerName.copyToUTF8 ((juce::uint8*) headerNamesAsChars[i]);

const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
headerValuesAsChars[i] = (char*) juce_calloc (headerValue.copyToUTF8 (0));
headerValue.copyToUTF8 ((juce::uint8*) headerValuesAsChars[i]);
}
}

sendWebViewToURL ((const char*) url.toUTF8(),
(const char**) headerNamesAsChars,
(const char**) headerValuesAsChars,
numHeaders,
postData != 0 ? (const char*) postData->getData() : 0,
postData != 0 ? postData->getSize() : 0);

for (int i = 0; i < numHeaders; ++i)
{
juce_free (headerNamesAsChars[i]);
juce_free (headerValuesAsChars[i]);
}

juce_free (headerNamesAsChars);
juce_free (headerValuesAsChars);
}

void goBack()
{
[webView goBack];
}

void goForward()
{
[webView goForward];
}

void stop()
{
[webView stopLoading];
}

void updateBounds()
{
HIRect r;
r.origin.x = (float) owner->getScreenX() - owner->getTopLevelComponent()->getScreenX();
r.origin.y = (float) owner->getScreenY() - owner->getTopLevelComponent()->getScreenY();
r.size.width = (float) owner->getWidth();
r.size.height = (float) owner->getHeight();
HIViewSetFrame (view, &r);
}

private:
WebBrowserComponent* const owner;
HIViewRef view;
WebView* webView;
DownloadClickDetector* clickListener;
void sendWebViewToURL (const char* utf8URL,
const char** headerNames,
const char** headerValues,
int numHeaders,
const char* postData,
int postDataSize)
{
NSMutableURLRequest* r = [NSMutableURLRequest
requestWithURL: [NSURL URLWithString: [NSString stringWithUTF8String: utf8URL]]
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval: 30.0];

if (postDataSize > 0)
{
[ r setHTTPMethod: @"POST"];
[ r setHTTPBody: [NSData dataWithBytes: postData length: postDataSize]];
}

int i;
for (i = 0; i < numHeaders; ++i)
{
[ r setValue: [NSString stringWithUTF8String: headerValues[i]]
forHTTPHeaderField: [NSString stringWithUTF8String: headerNames[i]]];
}

[[webView mainFrame] stopLoading ];
[[webView mainFrame] loadRequest: r];
}
WebBrowserComponentInternal (const WebBrowserComponentInternal&);
const WebBrowserComponentInternal& operator= (const WebBrowserComponentInternal&);
};

//==============================================================================
WebBrowserComponent::WebBrowserComponent()
: browser (0),
associatedWindow (0),
blankPageShown (false)
{
setOpaque (true);
}

WebBrowserComponent::~WebBrowserComponent()
{
deleteBrowser();
}

//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;

lastHeaders.clear();
if (headers != 0)
lastHeaders = *headers;

lastPostData.setSize (0);
if (postData != 0)
lastPostData = *postData;

blankPageShown = false;

if (browser != 0)
browser->goToURL (url, headers, postData);
}

void WebBrowserComponent::stop()
{
if (browser != 0)
browser->stop();
}

void WebBrowserComponent::goBack()
{
lastURL = String::empty;
blankPageShown = false;

if (browser != 0)
browser->goBack();
}

void WebBrowserComponent::goForward()
{
lastURL = String::empty;

if (browser != 0)
browser->goForward();
}

//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
if (browser == 0)
g.fillAll (Colours::white);
}

void WebBrowserComponent::checkWindowAssociation()
{
void* const window = getWindowHandle();

if (window != associatedWindow
|| (browser == 0 && window != 0))
{
associatedWindow = window;

deleteBrowser();
createBrowser();
}

if (browser != 0)
{
if (associatedWindow != 0 && isShowing())
{
browser->show();

if (blankPageShown)
goBack();
}
else
{
if (! blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this..

blankPageShown = true;
browser->goToURL ("about:blank", 0, 0);
}

browser->hide();
}
}
}

void WebBrowserComponent::createBrowser()
{
deleteBrowser();

if (isShowing())
{
WebInitForCarbon();
browser = new WebBrowserComponentInternal (this);
reloadLastURL();
}
}

void WebBrowserComponent::deleteBrowser()
{
deleteAndZero (browser);
}

void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL = String::empty;
}
}

void WebBrowserComponent::updateBrowserPosition()
{
if (getPeer() != 0 && browser != 0)
browser->updateBounds();
}

void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}

void WebBrowserComponent::moved()
{
updateBrowserPosition();
}

void WebBrowserComponent::resized()
{
updateBrowserPosition();
}

void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}

bool WebBrowserComponent::pageAboutToLoad (const String& url)
{
return true;
}

END_JUCE_NAMESPACE

+ 362
- 0
build/win32/platform_specific_code/juce_win32_WebBrowserComponent.cpp View File

@@ -0,0 +1,362 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
//==============================================================================
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#endif
#include "win32_headers.h"
#include <comutil.h>
#include <Exdisp.h>
#include <exdispid.h>
#ifdef _MSC_VER
#pragma warning (pop)
#pragma warning (disable: 4312 4244)
#endif
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
#include "../../../src/juce_appframework/gui/components/special/juce_ActiveXControlComponent.h"
//==============================================================================
class WebBrowserComponentInternal : public ActiveXControlComponent
{
public:
//==============================================================================
WebBrowserComponentInternal()
: browser (0),
connectionPoint (0),
adviseCookie (0)
{
}
~WebBrowserComponentInternal()
{
if (connectionPoint != 0)
connectionPoint->Unadvise (adviseCookie);
if (browser != 0)
browser->Release();
}
void createBrowser()
{
createControl (&CLSID_WebBrowser);
browser = (IWebBrowser2*) queryInterface (&IID_IWebBrowser2);
IConnectionPointContainer* connectionPointContainer = (IConnectionPointContainer*) queryInterface (&IID_IConnectionPointContainer);
if (connectionPointContainer != 0)
{
connectionPointContainer->FindConnectionPoint (DIID_DWebBrowserEvents2,
&connectionPoint);
if (connectionPoint != 0)
{
WebBrowserComponent* const owner = dynamic_cast <WebBrowserComponent*> (getParentComponent());
jassert (owner != 0);
EventHandler* handler = new EventHandler (owner);
connectionPoint->Advise (handler, &adviseCookie);
}
}
}
void goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
if (browser != 0)
{
LPSAFEARRAY sa = 0;
_variant_t flags, frame, postDataVar, headersVar;
if (headers != 0)
headersVar = (const tchar*) headers->joinIntoString ("\r\n");
if (postData != 0 && postData->getSize() > 0)
{
LPSAFEARRAY sa = SafeArrayCreateVector (VT_UI1, 0, postData->getSize());
if (sa != 0)
{
void* data = 0;
SafeArrayAccessData (sa, &data);
jassert (data != 0);
if (data != 0)
{
postData->copyTo (data, 0, postData->getSize());
SafeArrayUnaccessData (sa);
VARIANT postDataVar2;
VariantInit (&postDataVar2);
V_VT (&postDataVar2) = VT_ARRAY | VT_UI1;
V_ARRAY (&postDataVar2) = sa;
postDataVar = postDataVar2;
}
}
}
browser->Navigate ((BSTR) (const OLECHAR*) url,
&flags, &frame,
&postDataVar, &headersVar);
if (sa != 0)
SafeArrayDestroy (sa);
}
}
//==============================================================================
IWebBrowser2* browser;
//==============================================================================
juce_UseDebuggingNewOperator
private:
IConnectionPoint* connectionPoint;
DWORD adviseCookie;
//==============================================================================
class EventHandler : public IDispatch
{
public:
EventHandler (WebBrowserComponent* owner_)
: owner (owner_),
refCount (0)
{
}
~EventHandler()
{
}
//==============================================================================
HRESULT __stdcall QueryInterface (REFIID id, void __RPC_FAR* __RPC_FAR* result)
{
if (id == IID_IUnknown || id == IID_IDispatch || id == DIID_DWebBrowserEvents2)
{
AddRef();
*result = this;
return S_OK;
}
*result = 0;
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() { return ++refCount; }
ULONG __stdcall Release() { jassert (refCount > 0); const int r = --refCount; if (r == 0) delete this; return r; }
HRESULT __stdcall GetTypeInfoCount (UINT __RPC_FAR*) { return E_NOTIMPL; }
HRESULT __stdcall GetTypeInfo (UINT, LCID, ITypeInfo __RPC_FAR *__RPC_FAR*) { return E_NOTIMPL; }
HRESULT __stdcall GetIDsOfNames (REFIID, LPOLESTR __RPC_FAR*, UINT, LCID, DISPID __RPC_FAR*) { return E_NOTIMPL; }
HRESULT __stdcall Invoke (DISPID dispIdMember, REFIID /*riid*/, LCID /*lcid*/,
WORD /*wFlags*/, DISPPARAMS __RPC_FAR* pDispParams,
VARIANT __RPC_FAR* /*pVarResult*/, EXCEPINFO __RPC_FAR* /*pExcepInfo*/,
UINT __RPC_FAR* /*puArgErr*/)
{
switch (dispIdMember)
{
case DISPID_BEFORENAVIGATE2:
{
VARIANT* const vurl = pDispParams->rgvarg[5].pvarVal;
String url;
if ((vurl->vt & VT_BYREF) != 0)
url = *vurl->pbstrVal;
else
url = vurl->bstrVal;
*pDispParams->rgvarg->pboolVal
= owner->pageAboutToLoad (url) ? VARIANT_FALSE
: VARIANT_TRUE;
return S_OK;
}
default:
break;
}
return E_NOTIMPL;
}
//==============================================================================
juce_UseDebuggingNewOperator
private:
WebBrowserComponent* const owner;
int refCount;
EventHandler (const EventHandler&);
const EventHandler& operator= (const EventHandler&);
};
};
//==============================================================================
WebBrowserComponent::WebBrowserComponent()
: browser (0),
blankPageShown (false)
{
setOpaque (true);
addAndMakeVisible (browser = new WebBrowserComponentInternal());
}
WebBrowserComponent::~WebBrowserComponent()
{
delete browser;
}
//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
lastHeaders.clear();
if (headers != 0)
lastHeaders = *headers;
lastPostData.setSize (0);
if (postData != 0)
lastPostData = *postData;
blankPageShown = false;
browser->goToURL (url, headers, postData);
}
void WebBrowserComponent::stop()
{
if (browser->browser != 0)
browser->browser->Stop();
}
void WebBrowserComponent::goBack()
{
lastURL = String::empty;
blankPageShown = false;
if (browser->browser != 0)
browser->browser->GoBack();
}
void WebBrowserComponent::goForward()
{
lastURL = String::empty;
if (browser->browser != 0)
browser->browser->GoForward();
}
//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
if (browser->browser == 0)
g.fillAll (Colours::white);
}
void WebBrowserComponent::checkWindowAssociation()
{
if (isShowing())
{
if (blankPageShown)
goBack();
if (browser->browser == 0 && getPeer() != 0)
{
browser->createBrowser();
reloadLastURL();
}
}
else
{
if (browser != 0 && ! blankPageShown)
{
// when the component becomes invisible, some stuff like flash
// carries on playing audio, so we need to force it onto a blank
// page to avoid this..
blankPageShown = true;
browser->goToURL ("about:blank", 0, 0);
}
}
}
void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL = String::empty;
}
}
void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::moved()
{
}
void WebBrowserComponent::resized()
{
browser->setSize (getWidth(), getHeight());
}
void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}
bool WebBrowserComponent::pageAboutToLoad (const String&)
{
return true;
}
END_JUCE_NAMESPACE

+ 8
- 0
build/win32/vc8/JUCE.vcproj View File

@@ -4157,6 +4157,10 @@
RelativePath="..\..\..\src\juce_appframework\gui\components\special\juce_SystemTrayIconComponent.h"
>
</File>
<File
RelativePath="..\..\..\src\juce_appframework\gui\components\special\juce_WebBrowserComponent.h"
>
</File>
</Filter>
<Filter
Name="windows"
@@ -6280,6 +6284,10 @@
RelativePath="..\platform_specific_code\juce_win32_Threads.cpp"
>
</File>
<File
RelativePath="..\platform_specific_code\juce_win32_WebBrowserComponent.cpp"
>
</File>
<File
RelativePath="..\platform_specific_code\juce_win32_Windowing.cpp"
>


+ 1
- 0
docs/JUCE changelist.txt View File

@@ -9,6 +9,7 @@ Changelist for version 1.46
- new class: AudioProcessorGraph: This allows AudioProcessors to be efficiently wired together and run as a graph. I've converted the plugin host demo to now use this instead of its own graph rendering code.
- new class: AudioProcessorPlayer: This allows an audio i/o device to stream through an AudioProcessor (or an AudioProcessorGraph).
- new class QuickTimeAudioFormat, which uses QuickTime to implement an AudioFormat that can read .mov files and other formats that QT supports (e.g. mp3, aac, etc)
- new class: WebBrowserComponent, for embedding a web browser in your app
- AudioProcessor now has a few more pure virtual methods that you'll need to implement: acceptsMidi(), producesMidi() and getName()
- moved all the audio plugin hosting classes into the main juce tree
- Mac: the project now requires at least XCode V2.5


+ 3
- 0
src/juce_app_includes.h View File

@@ -713,6 +713,9 @@
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_SystemTrayIconComponent.h"
#endif
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#include "juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
#endif
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__
#include "juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h"
#endif


+ 135
- 0
src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h View File

@@ -0,0 +1,135 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#include "../juce_Component.h"
class WebBrowserComponentInternal;
//==============================================================================
/**
A component that displays an embedded web browser.
The browser itself will be platform-dependent. On the Mac, probably Safari, on
Windows, probably IE.
*/
class WebBrowserComponent : public Component
{
public:
//==============================================================================
/** Creates a WebBrowserComponent.
Once it's created and visible, send the browser to a URL using goToURL().
*/
WebBrowserComponent();
/** Destructor. */
~WebBrowserComponent();
//==============================================================================
/** Sends the browser to a particular URL.
@param url the URL to go to.
@param headers an optional set of parameters to put in the HTTP header. If
you supply this, it should be a set of string in the form
"HeaderKey: HeaderValue"
@param postData an optional block of data that will be attached to the HTTP
POST request
*/
void goToURL (const String& url,
const StringArray* headers = 0,
const MemoryBlock* postData = 0);
/** Stops the current page loading.
*/
void stop();
/** Sends the browser back one page.
*/
void goBack();
/** Sends the browser forward one page.
*/
void goForward();
//==============================================================================
/** This callback is called when the browser is about to navigate
to a new location.
You can override this method to perform some action when the user
tries to go to a particular URL. To allow the operation to carry on,
return true, or return false to stop the navigation happening.
*/
virtual bool pageAboutToLoad (const String& newURL);
//==============================================================================
/** @internal */
void paint (Graphics& g);
/** @internal */
void moved();
/** @internal */
void resized();
/** @internal */
void parentHierarchyChanged();
/** @internal */
void visibilityChanged();
//==============================================================================
juce_UseDebuggingNewOperator
private:
WebBrowserComponentInternal* browser;
bool blankPageShown;
String lastURL;
StringArray lastHeaders;
MemoryBlock lastPostData;
#if JUCE_MAC
void* associatedWindow;
void updateBrowserPosition();
void createBrowser();
void deleteBrowser();
#endif
void reloadLastURL();
void checkWindowAssociation();
WebBrowserComponent (const WebBrowserComponent&);
const WebBrowserComponent& operator= (const WebBrowserComponent&);
};
#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__

Loading…
Cancel
Save