How to communicate between two NativeWindows in Air - javascript

How can I send messages to or manipulate the contents of a NativeWindow instance from the parent window that created it?
I have read several places that to communicate between NativeWindow instances in the same application you need to "maintain a LocalConnection or write a whole whack of JavaScript". As it happens, I have no issue with writing a whole whack of JavaScript, but there doesn't seem to be any documentation on how to do it. Does anyone know what to do?
Thanks for any help you can give me!

Answering my own question here. "A whole whack of JavaScript" can be summed up in one ridiculous line:
var myWindow = air.NativeApplication.nativeApplication.openedWindows[intWindowCount].stage.getChildAt(0).window
myWindow.document.getElementById('status').innerHTML = "success";
This assumes you are using NativeWindow and loading HTML into using HTMLLoader and you're only loading one child. intWindowCount represents the number of opened windows (including the Introspector). 0 represents the number of children you created using the stage.addChild() method. The code I'm using is below in its entirety. There is likely some cleaning up to do, but it should be a good starting point for anyone that needs to do the same thing:
var htmlView = new air.HTMLLoader();
htmlView.width = 300;
htmlView.height = 500;
var objWindowOptions = new air.NativeWindowInitOptions();
objWindowOptions.transparent = false;
objWindowOptions.systemChrome = air.NativeWindowSystemChrome.STANDARD;
objWindowOptions.type= air.NativeWindowType.NORMAL;
var wWindow = new air.NativeWindow(objWindowOptions);
wWindow.x = objScreen.x;
wWindow.y = objScreen.y;
wWindow.width = objScreen.width;
wWindow.height = objScreen.height;
wWindow.activate();
wWindow.stage.align = "TL";
wWindow.stage.displayState = runtime.flash.display.StageDisplayState.FULL_SCREEN_INTERACTIVE;
wWindow.stage.scaleMode = "noScale";
wWindow.stage.addChild( htmlView );
htmlView.load( new air.URLRequest("pageTwo.html") );
setTimeout(function(){
objScreen.setWindowReference(air.NativeApplication.nativeApplication.openedWindows[intWindowCount].stage.getChildAt(0).window);
objScreen.setClock(cClock);
cClock.screen = objScreen;
},500);
The timeout at the end is a horrible, embarrassing hack. I'm only using it because I haven't found the right event yet to use with addEventListener().

Related

Cannot Update two EntityReferences?

Im feeling a little lost and I'm not even sure if I can give you the information you would need to help me. I'll try it anyway. Let's check this Code:
var task = new CRM.Entity("my_servicetask", mainView.activePage.context.taskid);
var currentUserId = CRM.config.settings.systemUserId;
var systemuserRef = new CRM.EntityReference("systemuser", currentUserId);
var activityId = mainView.activePage.context.activityid;
var serviceAppointmentRef = new CRM.EntityReference("serviceappointment", activityId);
task.Attributes["my_regardingaccountid"] = null;
task.Attributes["my_serviceappointmentid"] = serviceAppointmentRef;
task.Attributes["ownerid"] = systemuserRef;
await Utilities.promiseUpdate(task);
As you can see I'm setting an owner via 'ownerid'.
The Problem is that the owner is NOT set.
I've noticed that if I remove the Attribute Update on 'my_serviceappointmentid' the owner is set without any problems.
Putting the Attributes in a different order ends in 'ownerid' not being set, too.
Trying to write a 'task2' where only the 'ownerid' is set doesn't work (Also changing the order to do task2 first doesn't work).
The 'ownerid' is not set by any changes of 'my_serviceappointmentid'.
What is happening here? Why can't I Update the 'ownerid' together with 'my_serviceappointmentid' ?
Code is executed in Resco Mobile CRM

Pixi.js: How to Detect end of movie (callback for ended event?)

I have a project where I need to switch between full HD videos in a browser. I realized that my macbooks fans are starting to blow after a while. My assumption was that the video load is a bit too heavy for my browser, so I decided to give Pixi.js a try – with the hope that my GPU can handle the videos because I am in a webgl context. If that is wrong in the first place, we can abort here.
Anyway my question:
I load a movie file as a texture and I need to switch back to another movie, whenever that one has ended.
I tried to find some documentation but so far I have not found any callback events. Is there none? Do I have to manually add the total time of the video and then check against
videoTexture.baseTexture.source.currentTime?
So far I am switching between videos like this:
I have two different videoTextures and Sprites:
const videoTexture1 = new PIXI.Texture.from('video1.mp4');
const videoSprite1 = new PIXI.Sprite(videoTexture1);
videoSprite1.loop = true;
app.stage.addChild(videoSprite1);
const videoTexture2 = new PIXI.Texture.from('video2.mp4');
const videoSprite2 = new PIXI.Sprite(videoTexture2);
videoSprite2.visible = false;
app.stage.addChild(videoSprite2);
And then I do:
playAndShow(videoTexture2, videoSprite2);
stopAndHide(videoTexture1, videoSprite1);
function playAndShow(texture, sprite) {
sprite.visible = true;
texture.baseTexture.source.currentTime = 0;
texture.baseTexture.source.play();
}
function stopAndHide(texture, sprite) {
texture.baseTexture.source.currentTime = 0;
texture.baseTexture.source.pause();
sprite.visible = false;
}
But as I said I now need to detect when my video2 has ended and switch back to video1.
Thank you in advance for any help on this matter.
Cheers
merc
See: https://www.html5gamedevs.com/topic/44283-play-video-in-pixi-v5/?tab=comments#comment-247009
const texture = PIXI.Texture.from('data2/Video/intro/vidA1.webm');
const videoSprite = new PIXI.Sprite( texture );
/**#type {HTMLVideoElement}*/
const videoControler = videoSprite.texture.baseTexture.source;
seems that videoSprite.texture.baseTexture.source is https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement or more specifically https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement
You could use:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime
or other events/properties etc described in https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement

How to read memory at pointer (local_tbb.dwData) to get window handle

I've been lacking sleep so I'm just super over killing this one.
What I'm trying to do is get the handle from a window from a task bar button. Following this tutorial here: http://www.codeproject.com/Articles/10497/A-tool-to-order-the-window-buttons-in-your-taskbar. This is the specific part:
Getting the window handle
This was the really lucky part. I thought to myself: "Where would I
keep the window handle?". They must keep it somewhere, to enable the
activation of the correct window when a button is selected. The
obvious place to keep it would be in a structure for each button, and
the obvious place to keep the pointer to this structure would be in
the dwData field of each TBBUTTON.
So I had a look at the dwData fields, and they appeared to be
pointers. OK so far. Then I had a look at the memory they pointed to,
and there they were: the first field stores the window handle Smile |
:) )) Microsoft developers aren't so different, after all Smile | :)
So I successfully get the task bar button like this:
anyways this is how i get local_tbb:
remote_tbb = ralloc_alloc(struct_TBButton.size);
var rez = SendMessage(hToolbar, TB_GETBUTTON, i, ctypes.voidptr_t(remote_tbb));
if (!rez) { throw new Error('Failed on SendMessage of TB_GETBUTTON'); }
var local_tbb = new struct_TBButton();
var retRead = ralloc_read(remote_tbb, local_tbb.address());
var freed = ralloc_free(remote_tbb);
console.log('freed', freed);
for (var n in local_tbb) {
console.log(n, local_tbb[n]);
try {
console.log('toString', n, local_tbb[n].toString());
} catch (ignore) {}
}
and succesfully get the dwData field populated. From this console.log is when it does it on dwData:
"dwData" UInt64 { }
"toString" "dwData" "1499288"
So now I want to do what that guy said and Then I had a look at the memory they pointed to. So I'm trying to do that.
So I know I have to do something like this, but what IPC command should go into the SendMessage (currently I'm using 0x004A /** WM_COPYDATA **/ but this can't be right) and where should I put in the local_tbb.dwData as address?
var remote_hwnd = ralloc_alloc(ctypes.voidptr_t.size);
var smHwndRez = SendMessage(hToolbar, 0x004A /** WM_COPYDATA **/, local_tbb.idCommand, ctypes.voidptr_t(remote_hwnd));
console.log('smHwndRez=', smHwndRez);
var local_hwnd = ctypes.voidptr_t;
var retRead = ralloc_read(remote_hwnd, local_hwnd.address());
console.log('retRead=', retRead);
var freed = ralloc_free(remote_hwnd);
console.log('freed=', freed);
console.log('local_hwnd = ', local_hwnd, local_hwnd.toString(), uneval(local_hwnd));
Strictly speaking, this is not winapi, as this is not part of the API but undocumented implementation details.
From what I can gather:
Get the TBBUTTON data.
The .dwData contains a pointer to multiple(?) HANDLEs (voidptr_ts)
So reinterpret .dwData as a voidptr_t, i.e. new ctypes.voidptr_t(.dwData);
use ReadProcessMemory to read another pointer from the location .dwData points to. That is (supposed to be) your window handle.
So something like this:
var tbb = new TBButton();
...
var dataPtr = new ctypes.voidptr_t(tbb.dwData);
var handle = new ctypes.voidptr_t();
// Important: pass the address of |handle|, not |handle| itself.
if (!ReadProcessMemory(process, dataPtr, handle.address(), ctypes.voidptr_t.size, null)) {
throw new Error("Failed to read window handle");
}

Accessing contents of NativeWindow in a HTML AIR application?

I'm currently building a HTML/JS AIR application. The application needs to display to the user a different 'window' - dependant on whether this is the first time they've launched the application or not. This part is actually fine and I have the code below to do that:
if(!startUp()) { // this simply returns a boolean from a local preferences database that gets shipped with the .air
// do first time stuff
var windowOptions = new air.NativeWindowInitOptions();
windowOptions.systemChrome = 'none';
windowOptions.type = 'lightweight';
windowOptions.transparent = 'true';
windowOptions.resizable = 'false';
var windowBounds = new air.Rectangle(300, 300, 596, 490);
var newHtmlLoader = air.HTMLLoader.createRootWindow(true, windowOptions, true, windowBounds);
newHtmlLoader.load(new air.URLRequest('cover.html'));
}
else {
// display default window
// just set nativeWindow.visible = true (loaded from application.xml)
}
However, what I want to be able to do is manipulate the html content from within cover.html after it has loaded up. There seems to be plenty of tutorials online of how to move, resize, etc. the NativeWindow, but I simply want access to the NativeWindow's HTML content.
For example, how would I add a new paragraph to that page? I've tried the following:
newHtmlLoader.window.opener = window;
var doc = newHtmlLoader.window.opener.document.documentElement;
Using AIR's Introspector console, ....log(doc) returns [object HTMLHtmlElement].
Hmm, seems promising right? I then go on to try:
var p = document.createElement('p');
var t = document.createTextNode('Insert Me');
p.appendChild(t);
doc.appendChild(p);
...but nothing gets inserted. I've also tried the following replacements for doc:
var doc = newHtmlLoader.window.opener.document.body; // .log(doc) -> [object HTMLBodyElement]
var doc = newHtmlLoader.window.opener.document; // .log(doc) -> Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
...as well as the following with jQuery:
$(doc).append('<p>Insert Me</p>'); // again, nothing
So, anyone had any experience in accessing a NativeWindow's inner content programmatically? Any help will be greatly appreciated.
Hmm, so I think I may have found out how to do it...If we amend the original code and add an event listener on the loader:
var newHtmlLoader = air.HTMLLoader.createRootWindow(true, windowOptions, true, windowBounds);
newHtmlLoader.addEventListener(air.Event.COMPLETE, doEventComplete);
newHtmlLoader.load(new air.URLRequest('cover.html'));
You can then interact (assuming you're using jQuery) with the contents of the newly created window by using:
function doEventComplete(event) {
doc = $(event.currentTarget.window.document.body);
doc.append('<p>Insert Me!</p>')
}
:)
I'm not sure this has the effect you intended:
newHtmlLoader.window.opener = window;
var doc = newHtmlLoader.window.opener.document.documentElement;
What is does is set var doc = window.document.documentElement;, so 'doc' is your local document, not the one in the other window.
I think what you want is
var doc = newHtmlLoader.window.document.documentElement;
Do note that this will not work until the document has loaded.

Javascript text Resize

Without getting into the "should a text resizer be used or not" debate, I'd like some help with this...suffice to say that my clientele are from and older generation and may be sight impaired...
My script isn't functioning, and I'm not sure why. It's not live yet, so here's what I'm working with:
function fsize(size,unit,id){
var vfontsize = document.getElementById("#colleft");
if(vfontsize){
vfontsize.style.fontSize = size + unit;
}
}
var textsize = 14;
function changetextsize(up){
if(up){
textsize = parseFloat(textsize)+2;
}else{
textsize = parseFloat(textsize)-2;
}
}
I'm using onclick events to trigger the size changes. Thanks for your help!
1) You are not using "id" parameter in fsize()
2) Please post your onclicks... how are you using fsize and changetextsize together? You don't seen to be using "textsize" value anywhere ... Also, what happens when you click?
var vfontsize = document.getElementById("#colleft");
should, most likely, be
var vfontsize = document.getElementById("colleft"); // no hash
it seems to me like remnants from a jquery attempt or similar..
and then, tell us how you are calling these functions you have posted..

Categories

Resources