How should RenderTargetBitmap be used? - windows-runtime

In a Windows Universal App (WinRT) application, I am trying to capture a bitmap image of the current page (or a portion of it).
A google search indicated that I should use the class Windows::UI::Xaml::Media::Imaging::RenderTargetBitmap (more specifically its method RenderAsync() ) to capture the screen.
In a small sample application, I thus added this code (C++) :
auto pclRenderTargetBitmap = ref new Windows::UI::Xaml::Media::Imaging::RenderTargetBitmap;
Concurrency::create_task(pclRenderTargetBitmap->RenderAsync(pclElem,100,100)).then([&]() {
// handling code here
});
(pclElem is a FrameworkElement, more specifically a canvas, and is not null)
When I execute this code, the task is indeed created, but the lambda in the "then" is never called. It's as if RenderAsync() never terminates.
Does anyone have any experience with using this function in C++ ? What am I missing ?
Thanks for your answers.

Thanks to Andy Rich for his answer.
The problem was that the pclRenderTargetBitmap was going out of scope.
This can be solved by passing the lambda parameters by value :
auto pclRenderTargetBitmap = ref new Windows::UI::Xaml::Media::Imaging::RenderTargetBitmap;
Concurrency::create_task(pclRenderTargetBitmap->RenderAsync(pclElem,100,100)).then([=]() {
// handling code here
});

Related

MvvmCross with Template10

I'm attempting to create a version of the UWP app for the TipCalc sample here: https://github.com/MvvmCross/MvvmCross-Samples/tree/master/TipCalc
There already is a UWP version in the sample, which works fine. However I'm attempting to use Template10 (https://github.com/Windows-XAML/Template10) and I am having trouble getting the two libraries to work together.
MvvmCross wants me to modify the OnLaunched method, which has a reference to the root Frame. However, Template 10 instead abstracts this method exposing OnStartAsync which has no such reference...
There is an override in Template 10 for CreateRootFrame which seems like the right place to initialize the mvvmcross app, but this doesn't appear to work the way I expected...
Although the launched app DOES navigate to the appropriate page, and does also appear to initialize the view model (a breakpoint on the Start method in the associated VM does get hit), the page itself is blank.
comparing the Visual Tree of both apps reveals that while the existing UWP app from the sample has a Frame:
my Template10 App is loading a Modal Dialog:
I forked the original sample project and added the template 10 version, if you wish to try it for yourself: https://github.com/selaromdotnet/MvvmCross-Samples
Has anyone else been able to integrate MvvmCross with template 10? do you have any idea what i'm doing wrong, and any advice for the best practices in using both of these libraries together?
hmm it turns out that the ModalDialog is the expected behavior for Template10, according to the current docs here: https://github.com/Windows-XAML/Template10/wiki/Docs-|-Bootstrapper
I'm not familiar enough with Template10 to say why this is the case, but it does also say you can change this by overriding OnInitializeAsync, which I did, restoring the original frame in the same way the regular UWP project does:
public override async Task OnInitializeAsync(IActivatedEventArgs args)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
var setup = new Setup(rootFrame);
setup.Initialize();
}
await Task.CompletedTask;
}
This did the trick! I'm sure I still have a ways to go (I believe Template10 has it's own way of restoring state, so I probably shouldn't be doing it here)...
but this at least change finally got me to a working app. IF you know more about what I'm doing incorrectly here or what I should be doing instead, your comments would be greatly appreciated, thanks!

How to detect if I am in 'console' mode

I am writing an app that runs from the browser. However, some model functions are also called from the Yii2 console. Therefore, I am getting errors when trying to access variables that are set in the GUI.
Is it possible to tell which mode I am in? Is there some environment variable automatically set, or should I just set some session variable in the console app to indicate the state?
You can use
if (Yii::$app instanceof \yii\console\Application)
for console, and
if (Yii::$app instanceof \yii\web\Application)
for web.
Correct variant
Yii::$app->request->isConsoleRequest
There is a simpler way to figure this out without going through the Yii objects
if (php_sapi_name() == "cli") {
return;
}
...and it works for all PHP scripts
...and it is lighter
By default for console:
Yii::$app->id == 'basic-console'
And for web application:
Yii::$app->id == 'basic'
Yii::$app->id stores the id of the loaded configuration params. By default for console application it is 'basic-console' and for web application it is 'basic' (defined in configuration file)
Yii2 provides a number of different classes for application's console and for those of type web. In addition to this division of the mode of operation of the classes, there are also a set of rules governing the organization of the code of the application. The first, fundamental, it is the respect of giving the MVC Model object information, to view the management interface with the user and, finally, to the controller the role of coordination among them. In your case it seems to sense that a piece of code runs in console but referring to classes that provide a Web interface. Probably because in some Model classes were introduced with functions with HTML or other code that should not be there. If you need two separate applications should precisely separate applications that use a type controls
yii\console\Controller
and another that uses controller type web
yii\web\Controller.
Obviously Model classes will be common and, thanks to separate controller, be sure to invoke View appropriate to the type of user interface in use. I Hope this could be useful.
Works for nginx and apache:
function isConsole()
{
return 'cli' == php_sapi_name() || !array_key_exists('REQUEST_URI', $_SERVER);
}
Pure PHP:
global $argv;
if (empty($argv)) {
// Browser mode
}
else {
// Cli mode
}

Why is native .bind() so slow?

I recently came across this issue. For a project I'm working on, we were using .bind() way too often and it actually hit the performance quite hard considering that we only have 16ms for the rendering loop to do things.
So I did some jsperf and noticed that calling a bound function (besides of the extra garbage) is way slower than calling an unbound function or using .call on a function.
I literally changed every piece of code to avoid bindings and to use .call/.apply instead. Ding this i not only spawned less functions but also increased the performance of my app a great deal.
However, I was unsatisfied with this and wrote a new way of binding functions.
https://github.com/SebastianNette/FastBind
This is overwriting the native bind method with a .call/.apply approach.
And it runs 96% faster.
Doing some testings on nodejs is came to these results:
Calling a bound function is 20 times slower than calling an unbound function.
Calling a bound function with my own approach takes only 2 times the time of the unbound call.
So I was wondering what is wrong with the native binding function. Why does it behave like that? And which would be the best way to deal with that issue.
Most of my app code is now written like that:
var scope = this;
this.boundFn = function(a,b,c) { return scope.fn(a,b,c); };
Or even
this.callback = fn;
this.context = context;
this.callback.call(this.context);
I do prefer the latter because it doesn't spawn any new functions. However, sometimes I just do have to bind. (handlers, timers, etc).
My educated guess is that it makes a clone of the object you are using but replaces the underlying prototype of object. Instead of using a generic precompiled object from the page rendered code it now has to take two things:
The passed variable thats to be come this. analyse it, clone it. then inject the specified function thats to be called into the new object. Then execute the function in the new object. afterwards if no longer called clean it up.
The more complex and more scoping loops an object has the long the bind will take because the engine needs to traverse the scope tree of all functions and parameters to see what needs to be copied.
You are already using scoping, which I strongly advice. It is less memory intense and the engine does not have to copy the objects and then call the functions. And you get the added benefit that you can access properties from both objects.
In my experience binding is never truly needed. Just use setters and getters for properties, otherwise the scoped variables won't always change in the main object.
Take for example this snippet
function domagic() {
this.myproperty = "Hello ";
}
domagic.prototype = {
perform:function(){
var that = this;
var hello = "World";
setTimeout(function(){
// this in this contect is whatever runs timeout. not domagic
// I use this for jQuery and my own objects to get best
// of both worlds, but I always post a comment in a scope
// to remind myself what this and that refers to.
window.alert(that.myproperty+hello);
that.set("Goodbye ");
},2000);
},
set : function(what) {
this.myproperty = what;
}
};
magic = new domagic();
magic.perform();
setTimeout(function(){magic.perform();},2000);

Use MessageDialog/MessageBox with Portable Class Library and MVVM Light

I´m developing an App that will be available for Windows Phone 8 and the Windows Store. To reduce redundancy I´m using a Portable Class Library (PCL) and on top of that I'm trying to apply the MVVM pattern with the help of the MVVM Light PCL Toolkit. The ViewModels are placed in the PCL and are bound directly in the XAML of the Apps pages.
When the data is received without an error, everything works fine. But I don´t know how to get the exceptions/error message back to the App when errors do happen.
Inside the Windows Store App errors will show as a MessageDialog while the Wp8 App will use the MessageBox class. Obviously the PCL isn´t aware of any of these classes. What I´m not getting is how to know if a ViewModel ran into an error, and how to get the message inside the App. Is this even possible when the ViewModels are bound inside the XAML?
The code in the ViewModel (inside the PCL) looks like this:
DataService.Authenticate((token, error) =>
{
if (error != null)
{
// This is, obviously, not going to work.
MessageBox.Show(error.Message);
return;
}
Token = token;
});
So I have to save the error somehow and let the App itself know the error has occurred, and then call the matching way of showing the error to the user.
Currently I´m thinking of something like defining an Error-property inside the BaseViewModel and fill it when errors in the ViewModel occur. Then, in the CodeBehind of the pages, make them aware of the current ViewModel and bind a PropertyChanged-event to this Error-property. But I was not able to implement it yet, so I don't know if this is even the right way to go.
Do I have to step down from the idea to bind the ViewModels inside the XAML, and do I instead have to initialize them inside the pages Codebehind?
Your instinct is correct, but there are more than a few ways of going about this.
First and foremost, you can use Mvvm's Messaging library, which will allow your ViewModel to send messages directly to your View. Your View can then handle it in any way it wishes, including but not limited to using a MessageDialog.
Secondly, you can also create a Function or Action (likely the former) in your ViewModelLocator for ShowMessageDialog. This Function will likely take a string and return a Task. Then, after you initialize your ViewModelLocator initially, you can inject your ShowMessageDialog code. Your ViewModels can then use whatever platform's MessageDialogs that they please.
Ex:
Note: This code uses the BCL Async libraries that are accessible in Nuget. They work in the PCL just fine.
ViewModelLocator:
public static Func<string, Task> ShowMessageDialog { get; set; }
App.xaml.cs:
ViewModelLocator.ShowMessageDialog = (message) =>
{
// For Windows Phone
return TaskFactory.StartNew(() => MessageBox.Show(message));
// For Windows 8
MessageDialog md = new MessageDialog(message);
return md.ShowAsync().AsTask();
};
ViewModel:
await ViewModelLocator.ShowMessageDialog("This is my message.");
Secondary Note: The md.ShowAsync().AsTask(); must be run on the UI Thread. This means that you will have to invoke it via the dispatcher in the case that you are running it in a task asynchronously. This is possible using a similar method of injecting the use of the app's CoreDispatcher via the RunAsync method.
This means that you can, on any platform (Windows 8 and Windows Phone shown above), inject whatever Message Dialog system you want and use it in your PCL.
I would say that it is much easier to do the first method I suggested, as that is what it is there for, but the Function method version is definitely helpful at times.

Is there a way to run one of my apps functions after every minute in blackberry 10? [duplicate]

I searched the internet but there is very little documentation available on BlackBerry 10 development. Is there something in BlackBerry 10 that allows you to run a function forever after specified intervals of time? Like there is NSTimer in iPhone/Objective-C that can run a function after every x minutes or so.
As pointed by #Sorry_Boss, you can use QTimer on C++ code. If you want to do that in QML, you can also register it for use in QML in the constructor of your app class, like this:
qmlRegisterType<QTimer>("my.library", 1, 0, "QTimer");
Then, you can import it in your QML file:
import my.library 1.0
... and use it as an attached object to another component:
attachedObjects: [
QTimer {
id: timer
interval: 1000 // 1 second
onTimeOut {
// do something
}
}
]
Use QTimer.
QTimer timer = new QTimer(this);
timer->start(intervalTime);
Connect timeout signal of timer with your function.
QObject::connect(timer, SIGNAL(timeout()), this,
SLOT(yourFunction()));
Yes this can be done with QTimer
In cpp
QTimer *timer= new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
void AppName::update(){
//Do operation on timeout
}
As a more general answer, because you will likely run into the same problem again, you have to treat BB10 as a completely different operating system and development environment because it is. Unlike the old environment though, the documentation is actually quite good. For example finding information on timers is as simple as going to the Cascades documentation site, selecting API Reference and typing 'timer' into the filter text box.
You will also find a wealth of help in the form of sample applications and general documentation and guidelines.