I have my ActiveX COM component developed in VC6. I have created the firebreath plugin over it to be able to call the COM API from different browsers. I have one API in ActiveX component which pops up the CDialog UI, On Google Chrome browser dlg.DoModal() function is failing. Issue is only with Chrome it simply crashes at this call, in other browsers its working perfectly
On Windows 7 its working with Google Chrome as well issue is with Windows XP.
Please provide me some feedback on this issue.
I am attaching some code snippets here to give some idea of what I am trying to do
Firebreath Plugin code (Plugin name is FBTest):
bool FBTest::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *piw)
{
// The window is attached; act appropriately
try {
/* Now that we have the plugin window, create the ActiveX container
window as a child of the plugin, then create the ActiveX control
as a child of the container.
*/
FB::PluginWindowWin* pwnd = piw->get_as<FB::PluginWindowWin>();
if(pwnd != NULL)
{
HWND hWnd = pwnd->getHWND();
if(hWnd)
{
// Create the ActiveX control container
RECT rc;
::GetClientRect(hWnd, &rc);
m_fbTestWin.Create(hWnd, &rc, 0, WS_VISIBLE|WS_CHILD);
CComPtr<IUnknown> spControlTest;
//ETESTPROGID is prog id of activex component
HRESULT hrTest = m_fbTestWin.CreateControlEx(ETESTPROGID, NULL, NULL, &spControlTest, GUID_NULL, NULL);
if(SUCCEEDED(hrTest) && (spControlTest != NULL))
{
spControlTest.QueryInterface(&m_eTestAxCtl);
g_eTestAxCtl = m_eTestAxCtl;
if (m_eTestAxCtl)
{
//TODO: should we throw a FB exception here?
}
}
}
}
} catch(...) {
//TODO: should we throw a FB exception here?
}
return false;
}
void FBTest::TestFunc()
{
//hThread = (HANDLE)_beginthreadex(NULL, 0,&FBTest::Start, (void*)&m_eTestAxCtl, 0, &ThreadId);
if(m_eTestAxCtl)
{
try {
long nCode = -1;
//This is call to API of Activex component which will popup the dialog
HRESULT hr = m_eTestAxCtl->TestFunc();
//return nCode;
}
catch(...) {
}
}
}
Activex Component code :
STDMETHODIMP CTest::TestFunc()
{
//CTestDlg is ATL Dialog Object
CTestDlg TestDlg;
//At this call Google chrome is crashing
if(!TestDlg.DoModal())
return S_FALSE;
return S_OK;
}
I am calling TestFunc() API of plugin from one HTML page and its showing me the dailog in IE and firefox browsers but Chrome is crashing..
Please help.
Since you've given no info on when or how you're calling it, it's hard to be sure, but my guess is that you're calling DoModal on the main thread. That will cause the main thread to block.
You must never block the main thread in a plugin.
Try calling it on a different thread.
Related
I have an Android game developed with LibGdx version 1.9.9, which I am trying to export in HTML. I am using GWT (V-2.8.2). The game is running well in Android and doesn't have any issues. While exporting the game by running this command ./gradlew html:dist I am not getting any errors.
But when I am placing the exported library into the localhost and trying to access the game, first the default loader is appearing and then there is a blank screen with this error message:
GwtApplication: exception: (TypeError) : null is not an object (evaluating 'null.zY')
(TypeError) : null is not an object (evaluating 'null.zY')
This is happening in every browser - Safari, Chrome, Firefox.
The stack trace doesn't show any significant place of debug.
Any idea of what is the problem? Thanks.
HTML Gradle:
gwt {
gwtVersion='2.8.0' // Should match the gwt version used for building the gwt backend
maxHeapSize="2G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY
minHeapSize="1G"
src = files(file("src/")) // Needs to be in front of "modules" below.
modules 'com.package.gamename.GdxDefinition'
devModules 'com.package.gamename.GdxDefinitionSuperdev'
project.webAppDirName = 'webapp'
compiler {
strict = true;
disableCastChecking = true;
}
}
import org.wisepersist.gradle.plugins.gwt.GwtSuperDev
def HttpFileServer server = null
def httpFilePort = 8080
task startHttpServer () {
dependsOn draftCompileGwt
String output = project.buildDir.path + "/gwt/draftOut"
doLast {
copy {
from "webapp"
into output
}
copy {
from "war"
into output
}
server = new SimpleHttpFileServerFactory().start(new File(output), httpFilePort)
println "Server started in directory " + server.getContentRoot() + ", http://localhost:" + server.getPort()
}
}
task superDev (type: GwtSuperDev) {
dependsOn startHttpServer
doFirst {
gwt.modules = gwt.devModules
}
}
task dist(dependsOn: [clean, compileGwt]) {
doLast {
file("build/dist").mkdirs()
copy {
from "build/gwt/out"
into "build/dist"
}
copy {
from "webapp"
into "build/dist"
}
copy {
from "war"
into "build/dist"
}
}
}
task addSource {
doLast {
sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs)
}
}
tasks.compileGwt.dependsOn(addSource)
tasks.draftCompileGwt.dependsOn(addSource)
sourceCompatibility = 1.6
sourceSets.main.java.srcDirs = [ "src/" ]
eclipse.project {
name = appName + "-html"
}
Enter the superdev mode and activate source mapping and debugging and step through the source in Chrome, that's the way to find these problems.
Start with superdev parameter
Open the game's web page
Hit the arrow button at the top left corner
Hit the "compile" button
Source Maps are available in Chrome now, you get a "real" stack trace.
Is it possible to tell if another Chrome tab is using webkitSpeechRecognition?
If you try to use webkitSpeechRecognition while another tab is using it, it will throw an error "aborted" without any message. I want to be able to know if webkitSpeechRecognition is open in another tab, and if so, throw a better error that could notify the user.
Unless your customer is on the same website(you could check by logging the ip/browserprint in database and requesting by json) you cannot do that.
Cross domain protection is in effect, and that lets you know zilch about what happens in other tabs or frames.
I am using webkitSpeechRecognition for chrome ( does not work on FF) and I faced same issues like multiple Chrome tabs. Until the browser implement a better error message a temporary solutions that work for me:
You need to detect when a tab is focused or not in Chrome using
Javascript.
Make javascript code like this
isChromium = window.chrome;
if(isChromium)
{
if (window.addEventListener)
{
// bind focus event
window.addEventListener("focus", function (event)
{
console.log("Browser tab focus..");
recognition.stop();// to avoid error
recognition.start();
}, false);
window.addEventListener("blur", function (event)
{
console.log("Browser tab blur..");
recognition.stop();
}, false);
}
}
There's a small workaround for it. You can store the timestamp in a variable upon activating SpeechRecognition and when it exits after a few seconds of inactivity, it will be compared to a timestamp since the SpeechRecognition was activated. Since two tabs are using the API simultaneously, it will exit immediately.
For Chrome, you can use the code below and modify it base on your needs. Firefox doesn't support this yet at the moment.
var transcriptionStartTime;
var timeSinceLastStart;
function configureRecognition(){
var webkitSpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
if ('webkitSpeechRecognition' in window) {
recognition = new webkitSpeechRecognition();
recognition.continuous = true;
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onend = function() {
timeSinceLastStart = new Date().getTime() - transcriptionStartTime;
if (timeSinceLastStart < 100) {
alert('Speech recognition failed to start. Please close the tab that is currently using it.');
}
}
}
}
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition
I have followed this tutorial on setting up Parse push notification in a Windows Phone app. This is my code:
public App() {
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;
// Standard XAML initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
// Language display initialization
InitializeLanguage();
// Show graphics profiling information while debugging.
if (Debugger.IsAttached) {
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode,
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Prevent the screen from turning off while under the debugger by disabling
// the application's idle detection.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
// Initialize the Parse client with your Application ID and .NET Key found on
// your Parse dashboard
ParseClient.Initialize("grpTmrClet8K35yeXg2HQKK8wl59VeC9ijH0I0dn", "os8EfSFq9maPBtDJ91Mq0xnWme8fLANhttTPAqKu");
// After calling ParseClient.Initialize():
this.Startup += async (sender, args) =>
{
// This optional line tracks statistics around app opens, including push effectiveness:
ParseAnalytics.TrackAppOpens(RootFrame);
// By convention, the empty string is considered a "Broadcast" channel
// Note that we had to add "async" to the definition to use the await keyword
await ParsePush.SubscribeAsync("testchannel");
};
}
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private async void Application_Launching(object sender, LaunchingEventArgs e) {
await ParseAnalytics.TrackAppOpenedAsync();
}
When I send a push notification from the Parse dashboard it doesn't get received. I have tried running both on the emulator (Windows Phone 8.0) and device (8.1), with app in foreground, background and closed with the same negative result.
When I use a channel like "testchannel" above and use the segment options, the channel name appears in the dropdown list of options indicating that the app is at least connecting Parse, but it just wont receive the notifications.
Hope someone can help me identify what I am missing. Thanks in advance.
If you are developing a Windows Phone 8.1 app, make sure you've enabled toast notification in the manifest file.
I don't quite understand everything about Parse just yet, but this is what works for me.
In App.xaml.cs:
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
ParseClient.Initialize("wSjuNTbtjVLRaedXvOoaf9S5cTbkuQohTulNZ2vS", "nWZMhXRet9Wotlgikb9aUdKf5GFtRiMvduw7w68z");
}
We subscribe and enable analytics OnLaunched:
protected async override void OnLaunched(LaunchActivatedEventArgs e)
//Generated codes go here
await ParsePush.SubscribeAsync("testchannel");
await ParseAnalytics.TrackAppOpenedAsync();
That would simply do the trick. You should modify the code according to your needs. Hope this helps.
Our chrome extension does not work correctly anymore since version 37.0.2062.103 (It used to work correctly on chrome version 36.0.1985.143).
Specifically, the debugger API has stopped working for us when we use the DOMDebugger.
See the attached code: (background.js)
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
if( changeInfo.status == "loading" && tab.active){
var debugId = {tabId:tabId};
chrome.debugger.attach(debugId, '1.0', function() {
chrome.debugger.sendCommand(debugId, 'Debugger.enable', {}, function() {
chrome.debugger.sendCommand(debugId, "DOMDebugger.setEventListenerBreakpoint", {'eventName':'click'},
function(result) {
console.log('registering click');
});
});
});
}
});
chrome.debugger.onEvent.addListener(onEvent);
function onEvent(debuggeeId, method,params) {
if(method=="Debugger.paused"){
console.log('DONE!');
}
};
The extension successfully starts the debugger. we get the yellow debugger ribbon.
We also see the 'registering click' msg in the console. the result argument is an empty object {} (line 8).
However upon clicking on a button that has a click event listener nothing happens.
It used to work without any issues.
It seems like it regressed with https://codereview.chromium.org/305753005. One needs to call "DOM.enable" for it to work now. On the Chrome side, we should implicitly enable DOM domain upon setEventListenerBreakpoint for backwards compatibility. Unfortunately it already squeezed into the stable release.
Im pretty much new in sip development and trying to implement a windows phone 8 client using pjsip.
ive build the sample application from pjsip ,which creates pjsua app with telnet connectivity.
Right now ,what i dont get is,how will i use this library and integrate in my app without telnet,
i just need to put a manual dial pad and call from there,to accomplish this,what is going to be the procedure?
pjsip for android or iphone has two sample application ,csipsimple and siphon ,but pjsip for windows phone 8 has no application like this.
any help regarding the way to go ahead would be very helpful.
Thanks
Since you mention that you've tried the windows phone telnet app sample, I assume you've downloaded the PJSIP winphone source as mentioned in their wp8 getting started guide. To create a simple app that perform outgoing and receive incoming call as you mentioned, you can simply reuse this winphone project.
Open the winphone project and do:
Create new Windows Phone project and set this as startup project (let's call this project SIP_UI). This will serve as the UI. You can just create a "Call button" that will perform outgoing call later.
Follow the existing pjsua_wp WMAppManifest.xml settings for this SIP_UI. Especially the capabilities part. Your app won't work if you simply use the default settings.
Create new Windows Phone Runtime project (let's call this SIP_WINPRT). Create a class and a method inside of this class that will perform the actual call later.
Change property setting for SIP_WINPRT (right click SIP_WINPRT project -> property) by following the existing pjsua_wp_backend's. Change especially on the References, Additional include directories, and preprocessor definitions. Adjust the path accordingly.
Search for simple_pjsua.c in the winphone sample. And try to implement that in the class you've created in SIP_WINPRT. Sample that I've created:
#include "pch.h"
#include "backend.h"
#include "pjsua.h"
#define SIP_DOMAIN "dogdomain"
#define SIP_USER "dog"
#define SIP_PASSWD "dog"
using namespace backend;
using namespace Platform;
SipletRuntimeComponent::SipletRuntimeComponent()
{
}
/* Display error and exit application */
static void error_exit(const char *title, pj_status_t status)
{
//pjsua_perror(THIS_FILE, title, status);
pjsua_destroy();
exit(1);
}
/* Callback called by the library upon receiving incoming call */
static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
pjsip_rx_data *rdata)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(acc_id);
PJ_UNUSED_ARG(rdata);
pjsua_call_get_info(call_id, &ci);
//PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",
// (int)ci.remote_info.slen,
// ci.remote_info.ptr));
/* Automatically answer incoming calls with 200/OK */
pjsua_call_answer(call_id, 200, NULL, NULL);
}
/* Callback called by the library when call's media state has changed */
static void on_call_media_state(pjsua_call_id call_id)
{
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
// When media is active, connect call to sound device.
pjsua_conf_connect(ci.conf_slot, 0);
pjsua_conf_connect(0, ci.conf_slot);
}
}
/* Callback called by the library when call's state has changed */
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(e);
pjsua_call_get_info(call_id, &ci);
//PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,
// (int)ci.state_text.slen,
// ci.state_text.ptr));
}
int SipletRuntimeComponent::SipCall(int address)
{
/* Create pjsua */
pj_status_t status;
status = pjsua_create();
if (status != PJ_SUCCESS){
//Error in pjsua_create()
return -1;
}
/* Validate the URL*/
char url[50] = "sip:cat:cat#catdomain:5060";
status = pjsua_verify_url(url);
if (status != PJ_SUCCESS){
//Invalid URL given
return -1;
}
/* Init pjsua */
{
pjsua_config cfg;
pjsua_logging_config log_cfg;
pjsua_config_default(&cfg);
cfg.cb.on_incoming_call = &on_incoming_call;
cfg.cb.on_call_media_state = &on_call_media_state;
cfg.cb.on_call_state = &on_call_state;
pjsua_logging_config_default(&log_cfg);
log_cfg.console_level = 4;
status = pjsua_init(&cfg, &log_cfg, NULL);
if (status != PJ_SUCCESS){
//Error in pjsua_init()
pjsua_destroy();
return -1;
}
}
/* Add UDP transport. */
{
pjsua_transport_config cfg;
pjsua_transport_config_default(&cfg);
cfg.port = 5060;
status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
if (status != PJ_SUCCESS){
//Error creating transport
pjsua_destroy();
return -1;
}
}
/* Initialization is done, now start pjsua */
status = pjsua_start();
if (status != PJ_SUCCESS){
//Error starting pjsua
pjsua_destroy();
return -1;
}
/* Register to SIP server by creating SIP account. */
pjsua_acc_id acc_id;
{
pjsua_acc_config cfg;
pjsua_acc_config_default(&cfg);
cfg.id = pj_str("sip:" SIP_USER "#" SIP_DOMAIN);
cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
cfg.cred_count = 1;
cfg.cred_info[0].realm = pj_str(SIP_DOMAIN);
cfg.cred_info[0].scheme = pj_str("digest");
cfg.cred_info[0].username = pj_str(SIP_USER);
cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cfg.cred_info[0].data = pj_str(SIP_PASSWD);
status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
if (status != PJ_SUCCESS){
//Error adding account
pjsua_destroy();
return -1;
}
}
/* make call to the URL. */
pj_str_t uri = pj_str(url);
status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
if (status != PJ_SUCCESS){
//Error making call
pjsua_destroy();
return -1;
}
return address + 1;
}
Add SIP_WINPRT as a reference in SIP_UI project.
Call the SIP_WINPRT when the Call button is pressed.
Well, your problems doesn't seem to be related with PJSip but with UI Development.
I suggest that you create your UI (using XAML/C# or XAML/C++ and don't forget it must be a Windows Phone 8.0 Silverlight project). Then you start referencing the PJSip library.
Hope it helps!