Shortcut Menu with Dynamic Verbs for FILE_ATTRIBUTE_OFFLINE - winapi

I want that my Shortcut Menu via QueryContextMenu method (dynamic verbs), is visible as well for "Placeholders". Placeholders are Files that only exist locally virtual and needs to be downloaded from the cloud sync provider before the file can be read.
For this reason, I registered my Shortcut Menu via:
HKLM
{
NoRemove Software
{
NoRemove Classes
{
NoRemove CLSID
{
ForceRemove '%CLSID%' = s '%DESCRIPTION%'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
SupportedProtocols = s '*'
{
}
}
}
NoRemove AllSyncRootObjects
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove '%DESCRIPTION%' = s '%CLSID%'
}
}
}
}
}
}
In case the file really exists locally, my context menu entries will be shown. But in case it was being dehydrated (converted to a Placeholder), my context menu entries will not be shown. How can I register my ShellExtension, so that it will be shown always? Which kind of flags do I need to set? Sadly the internet is saying nothing about it.
I tried to learn from the ClourMirror example of Microsoft, which provides custom context menu entries, but sadly they don't work: https://github.com/microsoft/Windows-classic-samples/issues/156 . At the same time, I tried to learn from the "Always keep on this device" and "free up space" context menu entries, which are registered with the flags SkipCloudDownload (value: 0) and StorageProviderFlagsRequired (value:2) and looks promising. Especially SkipCloudDownload, but I set this flag on various positions with no change.
In the current state of the project, dynamic verbs are required, because of cross-platform compatibility. Thx for any hint.

The solution is adding to the COM object the empty value 'ContextMenuOptIn':
HKLM
{
NoRemove Software
{
NoRemove Classes
{
NoRemove CLSID
{
ForceRemove '%CLSID%' = s '%DESCRIPTION%'
{
val ContextMenuOptIn= s ''
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
NoRemove AllSyncRootObjects
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove '%DESCRIPTION%' = s '%CLSID%'
}
}
}
}
}
}
I found the solution here: https://github.com/pipeline-foundation/projects/issues/97
They had several issues regarding the same problem and could fix it by adding the additional 'flag'.

Related

ComboBox.Item.add(USB1) switch language----- globalization - VS 2019 WPF

I added ComboBox from MainWindow_OnContentRendered, when I start the program, and how ComboBox.Item will find the resource file to change different language?> .How can I put WPF ComboBox content globalization.Thank you.
hello.
A.
1.
public void MyComboBox()
{
ComboBox.Item.add(USB1)
ComboBox.Item.add(USB2)
ComboBox.Item.add(USB3)
}
2.
MainWindow_OnContentRendered
{
MyComboBox();
}
B.
//ResourceHelper.cs
public static void LoadResource(string ) {
var = (from d in _Resourcelist where d.ToString().Equals() select d).FirstOrDefault();
App.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(langType, UriKind.RelativeOrAbsolute) });
Thread.CurrentThread.CurrentCulture = cultureInfo;
hread.CurrentThread.CurrentUICulture = cultureInfo;}
The question sounds quite simple but is quite difficult to answer. I've just started a new WPF application from scratch, so I thought about the issue of switching to a different language at runtime in general. Of course you have to set CurrentCulture and CurrentUICulture like you do in your example. But what about the controls and their textual content?
My solution is a recursive method that I call with MainWindow.Content as parameter, and then it iterates deeper and deeper through the hierarchy of controls:
private static void ReloadAllText(object root)
{
if (root is TextBlock textBlock1)
{
UpdateBinding(textBlock1, TextBlock.TextProperty);
}
else if (root is ContentControl contentControl)
{
if (contentControl.Content is string)
{
UpdateBinding(contentControl, ContentControl.ContentProperty);
}
else
{
ReloadAllText(contentControl.Content);
}
}
else if (root is Panel panel)
{
foreach (var child in panel.Children)
{
ReloadAllText(child);
}
}
else if (root is ItemsControl itemsControl)
{
for (int cnt = 0, cntMax = VisualTreeHelper.GetChildrenCount(itemsControl); cnt < cntMax; cnt++)
{
if (VisualTreeHelper.GetChild(itemsControl, cnt) is TextBlock textBlock2)
{
ReloadAllText(textBlock2);
}
}
foreach (var item in itemsControl.Items)
{
ReloadAllText(item);
}
}
else if (root is Decorator decorator)
{
ReloadAllText(decorator.Child);
}
else if (root is IRaiseLanguageChanged customItem)
{
customItem.RaiseLanguageChanged();
}
}
The method consists of several branches:
For TextBlock (which is also used by default as the text display element inside other, more complicated controls), the Text property is set to the new value. In my case, I just update the binding. In your case, the new text may have a different source, I don't know your architechture.
For ContentControl (which is any control that has a Content property), it depends: If the content is just a string, I can set it to the new value right away. If it's more complex, then I have to recurse deeper.
For Panel (which is the base class for StackPanel, DockPanel, Grid etc.), I just recurse for each child element.
For ItemsControl (so also for your ComboBox!), I recurse for each item. I added the VisualTree part only because I have a control template for an empty list box consisting of only a TextBox saying "no items". If you bind ItemsSource to an enum type, you must renew the ItemsSourceProperty binding.
For Decorator (e.g. Border), I recurse for its single child.
For custom/self-made controls, I have defined a custom interface IRaiseLanguageChanged, so they must implement a RaiseLanguageChanged() method and handle the language switch themselves. After all, a control itself knows best what to do when the language changes.
This reflects only the set of controls I'm currently using. If you have additional control types, then you have to add respective branches. Please post them here, if you have any good ideas!

TornadoFX - how to fix ListView with a custom cell factory not updating properly when items are deleted?

I have a ListView displaying custom objects from my domain model, and if I use a custom cell factory to display the objects' properties in each row of the list, I get strange behaviour when I delete items. If the item is not the last in the list, the deleted item remains visible and the last item disappears. However, the item has been removed from the backing list as expected, and attempting to delete the phantom object has no further effect.
The display seems not to be refreshing properly, because after some arbitrary resizing of the window, the list eventually refreshes to its expected values. I've tried calling refresh() on the ListView manually but it has no noticeable effect.
Removing my custom cell factory fixes the problem, and I've seen other posts that have had a similar problem using standard JavaFX (ListView using custom cell factory doesn't update after items deleted) where the problem is fixed by changing the implementation of updateItem(Object item, boolean empty), but I can't work out how to do that in TornadoFX.
Here's an example that demonstrates the update issue (but not the phantom item, that only happens if the delete button is part of the custom cell):
package example
import javafx.scene.control.ListView
import tornadofx.*
data class DomainClass(val name: String, val flag1: Boolean, val flag2: Boolean, val info: String)
class UpdateIssue : App(UpdateIssueView::class)
class UpdateIssueView : View() {
val listSource = mutableListOf(
DomainClass("object1", true, false, "more info"),
DomainClass("object2", false, true, "even more info"),
DomainClass("object3", false, false, "all the info")
).observable()
var lst: ListView<DomainClass> by singleAssign()
override val root = vbox {
lst = listview(listSource) {
cellFormat {
graphic = cache {
hbox {
textfield(it.name)
combobox<Boolean> {
selectionModel.select(it.flag1)
}
combobox<Boolean> {
selectionModel.select(it.flag2)
}
textfield(it.info)
}
}
}
}
button("delete") {
action {
listSource.remove(lst.selectedItem)
}
}
}
}
Any help greatly appreciated!
The suggestion from #Edvin Syse to remove the cache block fixed this for me (although note that he also said a more performant fix would be to implement a ListCellFragment, which I haven't done here):
....
lst = listview(listSource) {
cellFormat {
graphic = hbox {
textfield(it.name)
combobox<Boolean> {
selectionModel.select(it.flag1)
}
combobox<Boolean> {
selectionModel.select(it.flag2)
}
textfield(it.info)
}
}
}
I noticed that the ComboBoxes don't show any other selectable values besides it.flag1 and flag2. You'll want to set the values property to true/false or true/false/null. You can then set the value item directly.
lst = listview(listSource) {
cellFormat {
graphic = hbox {
textfield(it.name)
combobox(values=listOf(true, false)) {
value = it.flag1
}
combobox(values=listOf(true, false)) {
value = it.flag2
}
textfield(it.info)
}
}
}

How to get all controls from tab

I need to get all controls from a tab on my form, I tried to use this option I found online but it didn't work ideas anyone?
var tabs = Xrm.Page.ui.tabs.get();
var fieldList = new Array();
for (var i in tabs)
{
var tab = tabs[i];
if(tab.getName() == "tab_2")
{
tab.sections.forEach(function (section, sectionIndex)
{
section.controls.forEach(function (control, controlIndex)
{
switch (control.getControlType())
{
case "standard":
case "lookup":
case "optionset":
var attribute = control.getAttribute();
if (attribute != null)
{
fieldList.push(attribute.getName());
}
break;
}
});
});
}
}
}
I just tried the code and it works.
It looks for a tab called tab_2 and then gets all controls within that tab and adds the control.name to an array (fieldList)
The result is a simple array of control names. When I ran this on my Contact form (with the Tab Name adjusted) I got the following results:
[
"fullname",
"nickname",
"employeeid",
"jobtitle",
"parentcustomerid",
"emailaddress1",
"telephone2",
"telephone1",
"mobilephone",
"fax",
"address1_composite",
"preferredsystemuserid",
"familystatuscode",
"spousesname",
"birthdate",
"description",
"ownerid",
"createdon"
]
If this is not working for you, I suggest the following:
Check the name of the CRM Tab
Depending on where you are running this (e.g. in a web resource or developer console) you may need to change the code context

Get Access property of a CodeElement

I'm writing an Add-in for VS 2010. Can't find answer for a question - How can i get the Access property of a CodeElement if it has that one.
I was trying reflection, but no results.
Ex. CodeElement is a class method
public void GetAccess (CodeElement codeElement)
{
object code = codeElement;
Type t = code.GetType();
t.GetProperty("Access") = vsCMAccess.vsCMAccessPublic;
}
But it doesnt work..
Help, please!
Access is only available on some types of CodeElements, so you'll need to check for the type of CodeElement you have, cast to the specific type and then retrieve the property.
Example:
if (codeElement.Kind == vsCMElementFunction)
{
return ((CodeFunction)codeElement).Access;
}
else if (codeElement.Kind == vsCMElementProperty)
{
return ((CodeProperty)codeElement).Access;
}

Mark ItemViewModel as dirty explicitly

I have address editor fragment, after user edit address I save changed model values to a database
fun saveAddressTable(tableViewEditModel: TableViewEditModel<Client>) {
tableViewEditModel.items.asSequence()
.filter { it.value.isDirty }
.forEach {
//do stuff }
}
Some adressess have obvious mistakes I can fix programmatically, however model is not marked as dirty after I change it.
For example,
fun autoEditAddressTable(tableViewEditModel: TableViewEditModel<Client>) {
tableViewEditModel.items.asSequence()
.forEach {
val client = it.value.item
client.localProperty.value = client.local.replace(",{2,}".toRegex(), ",")
}
}
Changes reflected in the UI, but model itself is not dirty. I've found markDirty() property method, but it doesn't help much. As model is not marked dirty, it fails filter criteria on save.
center = tableview ( controller.clients ) {
column("Local Address", Client::localProperty)
.prefWidth(400.0)
.makeEditable()
bindSelected(controller.clientModel)
enableDirtyTracking()
tableViewEditModel = editModel
}
Isn't TableViewEditModel expected to trace all model alteration? If client edits Local Address column manually, model becomes dirty.

Resources