I'm trying to use the SystemMediaTransportControls in an background audio app. I am using the MediaPlayer class to play the audio. Setting the music properties, thumbnail all seems to work fine, but setting the control buttons (i.e. "next" button) is not working at all. My use case is somewhat unique in that I can't get a complete playlist at once, the next track is only available through a internal method call.
Here is what I am doing:
This part is working fine, the volume control shows all the audio information and thumbnail correctly:
var playbackItem = new MediaPlaybackItem(source);
var displayProperties = playbackItem.GetDisplayProperties();
displayProperties.Type = Windows.Media.MediaPlaybackType.Music;
displayProperties.Thumbnail = RandomAccessStreamReference.CreateFromUri(new Uri(_currentTrack.AlbumArtUrl));
displayProperties.MusicProperties.AlbumArtist = displayProperties.MusicProperties.Artist = _currentTrack.Artist;
displayProperties.MusicProperties.Title = _currentTrack.SongTitle;
displayProperties.MusicProperties.AlbumTitle = _currentTrack.Album;
playbackItem.CanSkip = true;
playbackItem.ApplyDisplayProperties(displayProperties);
_player.Source = playbackItem;
This part is not working, the "Next" button is still disabled, the "Record" button is not showing.
var smtc = _player.SystemMediaTransportControls;
smtc.ButtonPressed += OnSMTCButtonPressed;
smtc.IsEnabled = true;
smtc.IsNextEnabled = true;
smtc.IsRecordEnabled = true;
I've been trying to look for answers online but was unable to find anything useful. Any answer is appreciated.
In UWP, apart SMTC, there is something like CommandManager - to properly work with your SMTC you will have to disable it. Just put the line:
mediaPlayer.CommandManager.IsEnabled = false;
once you initialize the player and it should work. You will find more information at MSDN:
If you are using MediaPlayer to play media, you can get an instance of the SystemMediaTransportControls class by accessing the MediaPlayer.SystemMediaTransportControls property. If you are going to manually control the SMTC, you should disable the automatic integration provided by MediaPlayer by setting the CommandManager.IsEnabled property to false.
Related
I've just started working with Windows Forms on Visual Studio 2019. I am most familiar with C++ and thus have been creating an application with C++/CLI. The basis of the project is that I have a schedule generating set of functions these are called in MyForm.h which is the main form originally launched. MyForm.h also opens MyForm2.h when a button is pressed. This MyForm2.h is where I have a problem. I want to allow the user to edit a series of specific settings for the schedule generator. The most user friendly way I've found to do this is with a datagrid using textboxes and checkmarks, but I need to have the original timeslots for the schedule in the datagrid for the user to edit when the open MyForm2.h.
I've looked all over to find how to set default values for a datagrid, but have only come up with two ok methods, both of which have some fatal flaws.
The first was from this microsoft guide.
The problem here is that the solution is written in c#, and I don't know how to implement it in a c++ program.
The second was from a few sites which generally displayed one of two formats which are displayed here in a way that is formatted to how I used them in my forms:
void InitializeComponent()
{
this->dgvStudents = (gcnew System::Windows::Forms::DataGridView());
this->dataGridViewTextBoxColumn1 = (gcnew System::Windows::Forms::DataGridViewTextBoxColumn());
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->dgvStudents))->BeginInit();
this->SuspendLayout();
this->dgvStudents->Columns->Add(this->dataGridViewTextBoxColumn1);
this->dgvStudents->Location = System::Drawing::Point(0, 0);
this->dgvStudents->Name = L"dgvStudents";
this->dgvStudents->Size = System::Drawing::Size(350, 100);
this->dgvStudents->TabIndex = 0;
//
// dataGridViewTextBoxColumn1
//
this->dataGridViewTextBoxColumn1->HeaderText = L"First Name";
this->dataGridViewTextBoxColumn1->Name = L"dataGridViewTextBoxColumn1";
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(638, 261);
this->Controls->Add(this->dgvStudents);
this->Name = L"MyForm3";
this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
this->Text = L"Exercise";
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->dgvStudents))->EndInit();
this->ResumeLayout(false);
// Option 1
this->dgvStudents->Rows[0]->Cells[0]->Value = "MLP";
// Option 2
this->dgvStudents->Rows->Add("MLP");
}
I have tried putting both options in several various parts of the InitializeComponent() function and it makes no difference. The problem with Option 2 of this second solution is that it will be removed from the code if I change anything in the [Design] part of the MyForm2.h code editor in VS and save it. Weirdly, Option 1 will not be displayed in the [Design] part of the code and instead I will get the error Member Cells not found in class System.Windows.Forms.DataGridViewRowCollection, but if I launch the debugger for the program, both options will be displayed exactly how I want them to be in the GUIs that appear. As previously meantioned though, both options will most likely be removed if I change anything else in the form designer. Any help would be greatly appreciated:)
I’m able to get a reference to, for instance, the “Scripts” panel; but it doesn’t seem to have the show and hide methods like panels created through scripting (see code below). How can I get it to show or hide programmatically, without invoking the corresponding menu item?
function findPanelByName(name) { // String → Panel|null
for (var iPanel = 0; iPanel < app.panels.length; iPanel++) {
var panel = app.panels[iPanel];
if (panel.name == name) {
return panel;
}
}
return null;
}
var scriptsPanel = findPanelByName('Scripts');
scriptsPanel.show(); // → “scriptsPanel.show is not a function”
A few things: Your method to get the right panel is unneccessarily complicated. You could just get the panel by using the panel collection's item method like so:
var scriptsPanel = app.panels.item('Scripts');
Then, you don't need to use show() to show the panel (as that method does not exist), but you can just show the panel, by settings its visible property to true:
scriptsPanel.visible = true;
And lastly, in case anybody else is supposed to use the script, you should make sure, that it works with international versions of InDesign as well. In my German version, the above panel for example would not exist, as it is named Skripte instead of Scripts. To avoid that you can use the language independent key of InDesign:
var scriptsPanel = app.panels.item('$ID/Scripting');
So, in conclusion, the entire script could be shortened up to this one-liner
app.panels.item('$ID/Scripting').visible = true;
I need to be able to change some variable's value, when app is closed.
I'm using exitEvent described here:
https://docs.nativescript.org/core-concepts/application-lifecycle
Also, i'm using local-storage plugin that works similar to javasctip's localstorage.
https://github.com/NathanaelA/nativescript-localstorage
My simple code looks like this:
var Observable = require("data/observable").Observable;
require("nativescript-dom");
var LS = require("nativescript-localstorage");
const application = require("tns-core-modules/application");
var page = require("ui/page");
exports.load = function (args) {
var page = args.object;
var model = new Observable();
var frame = require('ui/frame');
var ff = frame.getFrameById("dashboard");
var topmost = frame.topmost();
// This is exit event
application.on(application.exitEvent, (args) => {
LS.setItem('XX','111')
});
// What i will exit app, and run app again this will newer become 111,
it's null all the time
console.log(LS.getItem('XX'));
}
So, my question is - is possible to set any flag on app exit - it do not have to be localstorage (i've tested global variables to), to detect if exit was made, and based on this i can make a decisions that will help me ?
One of scenarios may be - i'm holding some flag in Localstorage that is TURE is user tapped "rememebr me" on the login screen.
So on exit i can check if he want's to be rememebered, if not i want to send user to login page and not dashboard when app is lauching....
Thank you.
EDIT:
I've tried applications-settings too, it will not work.
application.on(application.exitEvent, (args) => {
applicationSettings.setString("Name", "John Doe");
});
console.log(applicationSettings.getString("Name")); // not working
I suspect it's the issue with the nativescript-localstorage plugin. It writes the changes to file after a 250ms delay. At exit event you will give you very limited amount of time before your app is completely killed by system.
May be the Author had a reason for setting up this delay but I think its too much of time at least in this particular scenario so the changes are never written to file. You may raise a issue at the plugin's Github repo.
If you are looking for an immediate workaround, copy localstorage.js to your app and export internalSaveData from the file, so you could directly call it right after you finish setting your values.
I have an Android Phonegap app made with HTML5/Javascript/CSS. I'd like to suggest the users to choose between light and dark themes at the very first start of the app. When the user once chooses one of them this chose should be saved and relevant theme should be set as default at evry further start of the app. I have read some posts on this theme and am not sure which solution to take: Cache, cookies or HTML5 local storage (I am not familiar with any of them). Which one fits better to my app?
Thank you all!
localStorage wins, simply for persistence and ease-of-use:
// set the selected theme
localStorage.setItem("appTheme") = "dark";
...
var lsTheme = localStorage.getItem("appTheme"),
theme = (typeof lsTheme !== "undefined" ? lsTheme : "bright");
// do something with the selected theme; "bright" is default if no preference stored.
localStorage is the simplest and most effective solution like Kerri Shotts said however the setItem methods syntax is different to that displayed in her answer. As it takes to parameters one being the keyName the other being the keyValue like so: storage.setItem(keyName, keyValue); This then retrieved using the getItem method like so: var aValue = storage.getItem(keyName);.
e.g.
localStorage.setItem('bgcolor', 'red');
localStorage.setItem('font', 'Helvetica');
localStorage.setItem('image', 'myCat.png');
var currentColor = localStorage.getItem('bgcolor');
var currentFont = localStorage.getItem('font');
var currentImage = localStorage.getItem('image');
I am relatively new to the Win32/Windows API (non-MFC), and am trying to change the text colour of a static text control. It is already drawn to the screen in black, but I want to change it to another colour using the Windows Colour Chooser dialog, which is opened on clicking a button. Is this possible?
For the button, the WM_COMMAND message is handled on clicking. So far, I have written:
CHOOSECOLOR ccColour;
ccColour.lStructSize = sizeof(ccColour);
ccColour.hwndOwner = hWnd;
ccColour.rgbResult = crLabelTextColour;
ccColour.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&ccColour) == TRUE)
{
// crLabelTextColour is a COLORREF global variable assigned on loading the program
crLabelTextColour = ccColour.rgbResult;
}
This code, however, fails with an unhandled exception at the if statement, and I'm not sure why! Other examples seem to write code like this.
ChooseColor() crashes because you are not initializing the CHOOSECOLOR structure completely. You are only setting 3 fields, the rest will contain garbage. You'll need to zero-initialize everything, simple to do:
CHOOSECOLOR ccColour = {0};