Adobe-Runtime-Support
Adobe-Runtime-Support copied to clipboard
[Feature Request] Getting NativeWindow handle (HWND)
Feature Description
Getting NativeWindow handle (HWND) necessary to windows management and extend AIR functionality by native extensions for desktop platforms. With Windows platform it HWND.
With other desktop platforms it could be different like Electron uses: https://www.electronjs.org/docs/api/browser-window#wingetnativewindowhandle
Many native operations with windows requires handles/descriptors to use. Such getter would be very useful for AIR developers.
Related issues: https://tracker.adobe.com/#/view/AIR-3962230 https://github.com/Gamua/Adobe-Runtime-Support/issues/210
Known Workarounds
Write native extension with enumerating windows to find your AIR window. Or use NativeProcess to call separate application or utility script that make something like that.
Both of that approaches slow and not stable in some cases.
This is quite easy with a native extension, what exactly is the use case in AIR directly?
It's pretty easy with one AIR window but no so elegant when you working with multiple AIR windows which could be created/closed at runtime.
I have done it by window title searching. Also it can be done with checking window coordinates and may be some other not unique parameters.
Getting HWND directly from NativeWindow could be more correctly way to do that.
My case need such solution because of these points:
- Changing window styles properties dynamically at runtime (
GWL_STYLE,GWL_EXSTYLEetc). - Interact between non-AIR windows too. Order management etc.
- Working with Windows Messages queue (https://docs.microsoft.com/en-us/windows/win32/learnwin32/window-messages). Receive/dispatch events that cannot be handled via AIR directly.
So presumably this is just for a handle you’d use from within a native extension, maybe it could be a method added to the FRE... set of APIs called from the native layer?
@ajwfrost
For example, I have 2 different AS3/AIR windows (NativeWindow). I need to know handles for both of them. Not an array of all AIR process windows handles but "NativeWindow A - has handle 1234", "NativeWindow B - has handle 5678" etc.
There are two approaches for my opinion:
- Create new AS3
NativeWindow::nativeHandlegetter property (or some different naming). Then we can use that handle to pass it to native extension and use there. But it could be complex for non-Windows platfroms where handle not just "number". - Create FRE functions/APIs to get AIR windows handles. But there need somehow to distinguish windows from each other. May be it could be objects with title/coordinates.
May be there could be new FRE function that can get window handle from specified AS3/AIR
NativeWindow. From AS3/AIR side we can passNativeWindowinstance byExtensionContext::calland with native extension method do something like that (Windows extension code draft):
//Some native extension method
FREObject passWindow(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
HWND windowHWND;
FREGetObjectAsWindowHandle(argv[0], &windowHWND);//Some "new" function to get NativeWindow handle
//use windowHWND here
return NULL;
}
Second approach would be perfect for any of platforms and any cases.
Ah yeah I understand the use case with regards multiple windows.
You would probably need a way to commonly identify the windows between the AS3 and native layers so would have to be more than just a FRE function, or at least some common identifier added to both layers?
@marchbold
Yes, I tried to suggest approaches in comment above with AS3 getter method (window identifier) and another way to get such identifier/link via FRE function from passed AS3 NativeWindow object to native layer via ExtensionContext::call.
Passing the NativeWindow object in to the ANE function makes the most sense to me, we can check the code but I can’t imagine it will be that difficult to return an appropriate handle for Windows/MacOS..
I need this feature too.
We @Dallmeier-electronic would also like to have this feature for window identification. Currently, an external (display) service is doing this but it would be better if our application could provide this information on its own. We need this for z-sorting / arranging windows in the proper order. Our GUI is running in transparent mode with cut-out parts (BlendMode.ERASE) and reveals other application(s) (video) in the background.
Hi
Thanks for the reminder on this one, we have just been discussing it and looking into it a little. I think the danger is that providing the native window handle is something that could then cause problems if something then happened within the runtime that caused the handle to invalidate (i.e. if the window was closed...). So it's only "safe" if it's used in one thread at one time .. which is also the pattern Adobe took with the access of BitmapData and ByteArray objects. So if you're happy with this restriction, we could add two functions:
FREResult FREAcquireNativeWindowHandle(FREObject nativeWindow, FRENativeWindow* handle);
FREResult FREReleaseNativeWindowHandle(FREObject nativeWindow);
And then you would need to acquire the native handle, use it in your ANE function, and release it again.
The 'handle' type would then be platform-specific, e.g. HWND, NSWindow*, GtkWidget*
If that sounds okay, we can start looking at what's needed to actually implement this and roll out the new ANE headers/libraries.. I'm thinking this would be a desktop-only feature but if anyone sees this as necessary on Android/iOS please let me know!
thanks
@ajwfrost: Could you make the Process ID of a Native Window accessible at runtime?
@2jfw all the windows would be running in the same process so if you want the OS process ID, you can just use normal functions like GetCurrentProcessId() (for Win32) or getpid()? or am I misunderstanding what you're after here..
@ajwfrost As far as I know, each window has its own ProcessID. In our scenario a custom service gets the title of the NativeWindow and determines the processID and thus the related window handle to be able to change the z-order of the NativeWindow.
EDIT: It is a multi window application so I assume that by the unique title of each AIR native window the handle can be determined. I will add more details when I will receive an answer from the backend service team regarding what they currently do to get the window handle by the native window title
EDIT2: Sorry for the confusion - the service uses FindWindowW (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindoww) and retrieves the HWND, so there is no ID involved.
For Windows a property in NativeWindow like this :
var processId:int = stage.nativeWindow.processId;
and to use it in the extension :
IntPtr^ m_hwnd = IntPtr(processId);
@pol2095 that might be fine for Windows where everything is done through essentially a 'safe' pointer i.e. HWND type .. but on other platforms, what happens if we provide a pointer, and this is then used in a function call after it's been destroyed? hence the idea of Acquire/Release within an extension (you really shouldn't need this value within any ActionScript code!!)
thanks
@ajwfrost, let it be as described at
https://github.com/Gamua/Adobe-Runtime-Support/issues/236#issuecomment-785772231
or
https://github.com/Gamua/Adobe-Runtime-Support/issues/236#issuecomment-589941885
to work with NativeWindow handlers only at native side.
Any news about HWND, please get the HWND in as3 only for Windows, it's easier to implement. On Mac it's possible to get the window, iOS and Android not necessary for now.
Hi - actually, we had implemented this, it's just waiting in a 'next' feature branch where a bunch of API updates will be happening and where we'll need to therefore change the namespaces and version number away from "33.1". In discussion with Adobe they'd suggested we skip some numbers to avoid confusion with the Flash Player in China (currently at version 34 I think!) so we're going to bump it to version 50 which is also the version number that we use for Flash Player enterprise support ourselves.
So once we've got the iOS15 support done with the current 33.1 branch at the end of this month, we'll push out a beta for this as version 50.0....
thanks
Any news ?
Yes we ended up with a lot more to do on the 33.1 branch than we had thought :-( We have one more release on that about to land and then we'll try to get everything sorted out for a 50.0 beta. Sorry for the delays...
I see AIR 50.0.0.1 BETA, does it support this feature and how to use it on Windows ?
It should do but for a bug it seems... will get someone to check that out and do a quick sample..
Okay so there does seem to be an issue with the library not being updated .. which means it's not possible to do this currently, but will be fixed in the proper release. You can then do e.g.
var b : Boolean = extCtx.call("TestFunction", 12, stage.nativeWindow) as Boolean;
in ActionScript and handle it in C++
HWND hWnd = NULL;
FREResult res = FREAcquireNativeWindowHandle(argv[1], &hWnd);
if (res == FRE_OK)
{
::SetWindowPos(hWnd, NULL, value, value, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
FREReleaseNativeWindowHandle(argv[1]);
}
Thanks, this line is necessary ?
::SetWindowPos(hWnd, NULL, value, value, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
and what is-it value ?
Sorry, no that was just an illustration of how you can then use the window handle... so our test case just took a value (also passed from AS code) and then moved the window to that location (both x and y values).
We've apparently got some tweaks to make to the other platforms too..
Thanks, it work now.
This feature now available with AIR 50 for desktop platforms. Thanks!
Note:
To use it with Windows you need to include <windows.h> before FlashRuntimeExtensions.h in your native extension:
#include <windows.h>
#include "FlashRuntimeExtensions.h"
To use it with Linux you need to include <gtk/gtk.h> before FlashRuntimeExtensions.h in your native extension:
#include <gtk/gtk.h>
#include "FlashRuntimeExtensions.h"
To use it with macOS you need to include <Cocoa/Cocoa.h> before <Adobe AIR/FlashRuntimeExtensions.h> in your native extension:
#include <Cocoa/Cocoa.h>
#include <Adobe AIR/FlashRuntimeExtensions.h>
Related issue: https://github.com/airsdk/Adobe-Runtime-Support/issues/2311