-
-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add basic support for WinRT asynchronous methods #465
Conversation
Woah! Is this ready for review? That would be the best Christmas present! |
Yeah, I think this is finally ready for review :). |
import 'package:win32/winrt.dart'; | ||
|
||
void main() async { | ||
winrtInitialize(); | ||
final pIndex = calloc<Uint32>(); | ||
|
||
final picker = FileOpenPicker() | ||
..suggestedStartLocation = PickerLocationId.desktop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why, but neither the suggestedStartLocation
nor the viewMode
property appear to be working on my machine. I've tried changing them to various other values, but they don't seem to affect the presented dialog box. Can you replicate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FileOpenPicker.SuggestedStartLocation Property states:
The SuggestedStartLocation is not always used as the start location for the file picker. To give the user a sense of consistency, the file picker remembers the last location that the user navigated to and will generally start at that location.
As for the viewMode
property, I can't get it to work either. I'm installing Visual Studio right now. I'll try this example in a UWP app to see if this works properly there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, it doesn't work in a UWP app either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very strange. Investigating here too...
/// [target] must be a WinRT object that implements the | ||
/// `IInitializeWithWindow` interface (e.g. `FileOpenPicker`). | ||
/// | ||
/// [hwnd] represents the handle of the window to be used as the owner window. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if there are only specific types of HWND
that are valid. I used GetActiveWindow()
(which I would have thought would be the natural choice), and got an error: Error 0x80070578: Invalid window handle.
, which suggests that there's some specific criteria beyond being a valid HWND
. I wasn't able to find documentation that answered this beyond this article.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if there are only specific types of HWND that are valid. I used GetActiveWindow() (which I would have thought would be the natural choice), and got an error: Error 0x80070578: Invalid window handle., which suggests that there's some specific criteria beyond being a valid HWND. I wasn't able to find documentation that answered this beyond this article.
I don't know. I found GetConsoleWindow()
and GetShellWindow()
by trial and error.
I just noticed that GetForegroundWindow()
works for both console and Flutter apps (yay!). I wonder, should I make the necessary changes so that we use GetForegroundWindow()
everywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetForegroundWindow()
is good, but it's not perfect -- for example, if there's another window from another process that has gained focus, it will become the parent for the file picker. That's why I'm a bit bemused that GetActiveWindow()
isn't working here, since that means "the current window from the current process". (More here: https://devblogs.microsoft.com/oldnewthing/20081006-00/?p=20643)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. It was too good to be true anyway :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to explain it:
https://devblogs.microsoft.com/oldnewthing/20190412-00/?p=102413
(TL;DR Not every window has a CoreWindow
associated with it. We ought to figure out how to do IInitializeWithWindow
from Dart).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some general comments above. Hopefully helpful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably a little more iteration to be done on the example, but I think we're good to merge this as a baseline. This is awesome work, @halildurmus. I don't think I could have gotten there myself. Thank you so much!
Thank you. Let's do this 🎉. |
Awesome would love to give this a try! |
Fixes #39
Fixes #97
Adds support for WinRT asynchronous methods that return IAsyncAction or IAsyncOperation delegates. This is achieved by polling their status property every
10 milliseconds
(I don't have a strong opinion on what this value should be) until it completes.The other WinRT projections use the completed callback but we can't use that at the moment as async callbacks are not supported yet. This also prevents us from adding support for the asynchronous methods that return IAsyncActionWithProgress and IAsyncOperationWithProgress delegates (they report progress updates to callers through their progress callback).
Furthermore, I added IInitializeWithWindow interface and a wrapper for it (in
winrt_com_interop_helpers.dart
). This is necessary for APIs that depend onCoreWindow
(Display WinRT UI objects that depend on CoreWindow explains this).Also added the
BasicProperties
class and partially generated theStorageFile
APIs (I'll fully generate them later as StorageFile has so many dependencies).