SHAddToRecentDocs doesn't add my file to recent documents - recent-documents

Double clicking on a file in Explorer correctly adds the file to the recent list for my application and I can open it again from the popup menu on my application which I have pinned on the start menu.
I've got a special file manager in the application so I am using SHAddToRecentDocs to add the projects opened in the application to recent files. But it just doesn't happen and I can't find what the problem is.
Here's what I got in the registry:
HKEY_CLASSES_ROOT\.abc\Content Type = application/MyApp
HKEY_CLASSES_ROOT\.abc\(Standard) = MyAppProjectFile
HKEY_CLASSES_ROOT\MyAppProjectFile\shell\open\command\(Standard) = "C:\MyApp\MyApp.exe" %1
HKEY_CLASSES_ROOT\Applications\MyApp.exe\shell\open\command\(Standard) = "C:\MyApp\MyApp.exe" %1
There are no other keys under HKCR\Applications\MyApp.exe.
Like I said, I can open applications by double clicking on them in Explorer, they get added to the recent documents and everything looks fine. I can open them from the popup fine.
My SHAddToRecentDocs call, which gets a correct path, doesn't seem to be doing anything at all. No link appears in the recent documents folder.
Here's the C# code I use to run SHAddToRecentDocs:
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
static extern void SHAddToRecentDocs(ShellAddToRecentDocsFlags flags, string file);
[Flags]
public enum ShellAddToRecentDocsFlags
{
Pidl = 0x001,
Path = 0x002,
}
/// <summary>
/// Adds the file to recent files list in windows.
/// </summary>
/// <param name="fullPath"> Name of the file. </param>
public static void AddFileToRecentFilesList(string fullPath)
{
SHAddToRecentDocs(ShellAddToRecentDocsFlags.Path, fullPath);
}

If turned out that a fix to a FxCop code warning was the reason this didn't work.
The ShellAddToRecentDocsFlags API was defined as follows:
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
static extern void SHAddToRecentDocs(ShellAddToRecentDocsFlags flags, string file);
Changing it to the following fixed the issue:
[DllImport("Shell32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)]
static extern void SHAddToRecentDocs(ShellAddToRecentDocsFlags flags, [MarshalAs(UnmanagedType.LPStr)]string file);

Related

How to remove white touch dot on Windows 10

I am creating a kiosk–like application for a Windows 10 PC with a touch screen as its only input interface. What I want to remove is the white touch dot that is displayed as a visual touch feedback (mostly together with a circle, which can be turned off).
Does anyone know how to do this?
I have already searched the registry if there was a cursor (*.cur) file which is used but did not find any results. Due to that I guess that the touch feedback is displayed differently.
Just to make sure — I do not want to lose touch functionality, only the visual feedback needs to be gone.
For WPF programs:
In order to remove the touch feedback from WPF elements, it's enough to set Stylus.IsTapFeedbackEnabled dependency property to false. You may want to do that within styles:
<Style x:Key="yourStyle">
<Setter Property="Stylus.IsTapFeedbackEnabled" Value="False" />
</Style>
The white touch dot you cited is actually a cursor. Whenever you touch the screen, Windows replaces the cursor set for the control with the touch cursor. To avoid this honestly ugly behavior, you can set your cursor to Cursors.None, so that the cursor will be hidden. Paste the code below inside your Window and you won't see your white touch dot anymore.
protected override void OnPreviewTouchDown(TouchEventArgs e)
{
base.OnPreviewTouchDown(e);
Cursor = Cursors.None;
}
protected override void OnPreviewTouchMove(TouchEventArgs e)
{
base.OnPreviewTouchMove(e);
Cursor = Cursors.None;
}
protected override void OnGotMouseCapture(MouseEventArgs e)
{
base.OnGotMouseCapture(e);
Cursor = Cursors.Arrow;
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
base.OnPreviewMouseMove(e);
if (e.StylusDevice == null)
Cursor = Cursors.Arrow;
}
Your cursor will always be set to Cursors.Arrow when you're using the mouse, though, so you could lose a different cursor you had set to the window. It'd be an easy task to tweak this behavior — my code only serves for demonstration purposes.
For Windows Forms programs:
Looking at the Reference Source for Stylus.IsTapFeedbackEnabled, I've figured out the P/Invoke calls that happen under the hood. Here's what I've come up with for Windows Form applications:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace TouchableWinform
{
public class TouchableForm : Form
{
private const string TOUCH_SUPPORT_CATEGORY = "Touch support";
private const bool IS_PRESS_AND_HOLD_ENABLED_DEFAULT_VALUE = false;
private const bool IS_FLICKS_ENABLED_DEFAULT_VALUE = false;
private const bool IS_TAP_FEEDBACK_DEFAULT_VALUE = false;
private const bool IS_TOUCH_FEEDBACK_DEFAULT_VALUE = false;
/// <summary>
/// Gets or sets a values indicating whether press and hold is enabled.
/// </summary>
[Category(TOUCH_SUPPORT_CATEGORY), Description("Gets or sets a values indicating whether press and hold is enabled."), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(IS_PRESS_AND_HOLD_ENABLED_DEFAULT_VALUE)]
public bool IsPressAndHoldEnabled
{
get;
set;
} = IS_PRESS_AND_HOLD_ENABLED_DEFAULT_VALUE;
/// <summary>
/// Gets or sets a value indicating whether flicks are enabled.
/// </summary>
[Category(TOUCH_SUPPORT_CATEGORY), Description("Gets or sets a value indicating whether flicks are enabled."), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(IS_FLICKS_ENABLED_DEFAULT_VALUE)]
public bool IsFlicksEnabled
{
get;
set;
} = IS_FLICKS_ENABLED_DEFAULT_VALUE;
/// <summary>
/// Gets or sets whether a value indicating whether tap feedback is enabled.
/// </summary>
[Category(TOUCH_SUPPORT_CATEGORY), Description("Gets or sets whether a value indicating whether tap feedback is enabled."), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(IS_TAP_FEEDBACK_DEFAULT_VALUE)]
public bool IsTapFeedbackEnabled
{
get;
set;
} = IS_TAP_FEEDBACK_DEFAULT_VALUE;
/// <summary>
/// Gets or sets whether a value indicating whether touch feedback is enabled.
/// </summary>
[Category(TOUCH_SUPPORT_CATEGORY), Description("Gets or sets whether a value indicating whether touch feedback is enabled."), EditorBrowsable(EditorBrowsableState.Always), DefaultValue(IS_TOUCH_FEEDBACK_DEFAULT_VALUE)]
public bool IsTouchFeedbackEnabled
{
get;
set;
} = IS_TOUCH_FEEDBACK_DEFAULT_VALUE;
/// <summary>
/// Processes Windows messages.
/// </summary>
/// <param name="m">The Windows <see cref="Message"/> to process.</param>
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x2CB:
m.Result = new IntPtr(1);
break;
case 0x2CC:
uint flags = 0;
if (!IsPressAndHoldEnabled)
flags |= 1;
if (!IsTapFeedbackEnabled)
flags |= 8;
flags |= IsTouchFeedbackEnabled ? (uint)0x100 : 0x200;
if (!IsFlicksEnabled)
flags |= 0x10000;
m.Result = new IntPtr(flags);
break;
default:
base.WndProc(ref m);
break;
}
}
}
}
Unfortunately, for some reason I couldn't still figure out, it doesn't quite look to be working. I'm open to any suggestions.
In Windows 10, you can use pointer messages to handle touches. This would make WPF act like native UWP app behavior. The white dot will disappear and touch move animation get fixed.
If you are using .NET Core, add this line to your App.xaml.cs constructor:
public partial class App : Application
{
public App()
{
AppContext.SetSwitch("Switch.System.Windows.Input.Stylus.EnablePointerSupport", true);
}
}
For .NET Framework, you should add App.config file to project. The contents are shown below:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
</startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true" />
</runtime>
</configuration>
Sources:
How to enable pointer message support in WPF .NET Core
WPF will have a touch offset after trun on the WM_Pointer message

Creating A Per-View Resource File In MVC

I am converting a localized WebForms application to MVC5. Most of the examples I have seen for MVC have a single resource - resx - file (per language) for the entire application.
Is it possible, to have a separate file for each view? If so, is there an example of how to reference the said file?
UPDATE: I would like to leave the resource files uncompiled if possible. This would allow us to edit the RESX files on the fly without having to recompile the site everytime.
Below is the procedure I had in WebForms. I am essentially trying to reproduce this in MVC5.
public string LocalizeText(Page CurrentPage, string resourceKey)
{
string localizedText = string.Empty;
// LOOK FOR LOCALIZED TEXT
String filePath = string.Empty;
if (!String.IsNullOrEmpty(CurrentPage.Request.GetFriendlyUrlFileVirtualPath()))
{
filePath = CurrentPage.Request.GetFriendlyUrlFileVirtualPath(); // FOR FRIENDLY URLS
}
else
{
filePath = CurrentPage.Request.CurrentExecutionFilePath; // FOR "UNFRIENDLY" URLS (THOSE WITH A FILE EXTENSION VISIBLE)
}
try
{
localizedText = Convert.ToString(HttpContext.GetLocalResourceObject(filePath, resourceKey, System.Globalization.CultureInfo.CurrentCulture)).Trim();
}
catch (Exception ex)
{
HttpContext.Current.Response.Write(ex.ToString() + "<br />" + filePath);
}
return localizedText;
}
The resource files would be located in the App_LocalResources folder.
Yes, it is possible to have a separate resource file for a view. As a really simple, and pretty dull example (sorry about that :-)), consider the following view model:
using _31662592.Resources;
using System.ComponentModel.DataAnnotations;
public class HomeViewModel
{
[Display(Name = "WelcomeHeader", ResourceType = typeof(HomeResources))]
public string WelcomeHeader { get; set; }
[Display(Name = "WelcomeMessage", ResourceType = typeof(HomeResources))]
public string WelcomeMessage { get; set; }
}
Here, I'm making use of the Display attribute, which has support for localisation. So in my case, the resource file I created looks like this:
As you can see, the ResourceType property corresponds with the type of your resource file (i.e. HomeResources in my case), and the Name property corresponds with the name of the string in the resource file which you wish to bind the property to.
Nothing fancy in the action:
public ActionResult Index()
{
return View(new HomeViewModel());
}
The view is very simple too:
#model _31662592.Models.HomeViewModel
<h1>#Html.DisplayNameFor(m => m.WelcomeHeader)</h1>
<p>#Html.DisplayNameFor(m => m.WelcomeMessage)</p>
You can even use the resources inline in your views, such as:
#using _31662592.Resources
<h1>#HomeResources.WelcomeHeader</h1>
<p>#HomeResources.WelcomeMessage</p>
In case you have any problems, you should make sure that:
The Build Action for the resource is set to "Embedded Resource".
The Custom Tool for the resource is set to "PublicResXFileCodeGenerator".
Both of these options can be set by right-clicking on the resource file and selecting Properties. Those options will then be shown in the properties dockable window. Finally, if you wish to reference the resource file from another project, make sure it's set to Public rather than internal, which you can set by double-clicking the resource file to open it as normal, then changing its access modifier from internal to public.

Using property files in Web Applications [duplicate]

This question already has answers here:
How to get properties file from /WEB-INF folder in JSF?
(3 answers)
Closed 7 years ago.
I'm developing a web application(this is my first time) and pretty confused about using property files. I don't know where to put the property files.
The problem is that i have put it under the WEB_INF folder. And when i test run it as a Java Application to check whether Database connections are working according to the properties in the property file it is working without any problem.
But when i run it in a Server as a Web Application it fails to load the properties file saying it could not find the file in the path specified. I tried using every possible path i could give and changing the file directories within the whole project. But I kept getting the same error.
Then i changed my class again from scratch thinking there's some kind of a bug withing my code where i load the properties file. And it seems that it could not find the file either when deployed as a Web App. But my test application works fine. Where do i put this file and how do i use it. I have read #BalusC's answer in this thread https://stackoverflow.com/a/2161583/2999358 but i have no idea why this happens. Can someone help me on this?
I'm using Tomcat 8, Eclipse IDE and building on JSF framework.
Class where i load my properties file
public class ConfigCache {
private static final File FILE = new File("./WebContent/WEB-INF/conf/config.properties");
private static final Properties PROPERTIES = new Properties();
public static final String JDBC_DRIVER = ConfigCache.getProperty("db.driverName");
public static final String DATABASE_URL = ConfigCache.getProperty("db.url");
public static final String DATABASE_USERNAME = ConfigCache.getProperty("db.user");
public static final String DATABASE_PASSWORD = ConfigCache.getProperty("db.pass");
public ConfigCache() {
}
public static String getProperty(String key) {
if (PROPERTIES.isEmpty()) {
loadProperties();
}
Object value;
return (value = PROPERTIES.get(key)) == null ? "" : value.toString();
}
private static void loadProperties() {
if (!FILE.exists()) {
throw new IllegalArgumentException("The 'config.properties' has not been found.");
}
try {
FileInputStream fis = null;
try {
fis = new FileInputStream(FILE);
PROPERTIES.load(fis);
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException exp) {
System.out.println("IOException #" + ConfigCache.class + " # loadProperties() : " + exp);
}
}
} catch (Exception exp) {
System.out.println("Exception #" + ConfigCache.class + " # loadProperties() : " + exp);
}
}
}
Folder Structure
Try With this.
put the property in src folder.
Your file is in the WEB-INF directory. This means it's part of the war and reachable as part of the class path. That's perfectly ok, since it makes it portable and independant of the web container installation (e.g. Tomcat).
You can load any file in the class path as a resource:
getClass().getResourceAsStream("/conf/config.properties")
This means you can write your code like this:
private static void loadProperties() {
InputStream is = getClass().getResourceAsStream("/conf/config.properties");
PROPERTIES.load(fis);
}
(Error handling omitted)
You can explode (unzip) your war/ear file and see the contents or folder structure of it and find why your code doesnt work. The reason is that the folder WebContent doesnt exist in your ear/war , but does exist only when run via eclipse. This is the reason why its always better to follow the solution provided in the link posted so that you can retrieve the porperty files from classpath. The below code fetches your property file in eclipse but not in the server.
private static final File FILE = new File("./WebContent/WEB-INF/conf/config.properties");
Contents of WAR file (from JournelDev), it contains WEB-INF directory but there would be no WebContent directory above it

Multiple Processes using one Logging Application Block log file

We use the logging application block in our ASP.NET 2.0 application which is called in the following way:
public class BaseLogEntry : LogEntry
{
public void CloseLog()
{
try
{
Logger.Writer.Dispose();
}
catch (Exception)
{ }
}
}
public class GeneralLogEntry : BaseLogEntry
{
/// <summary>
///
/// </summary>
/// <param name="message"></param>
public GeneralLogEntry(string message) : this(message, 2) { }
/// <summary>
///
/// </summary>
/// <param name="message"></param>
/// <param name="priority"></param>
public GeneralLogEntry(string message, int priority): base()
{
Categories.Add("General");
Priority = priority;
Severity = System.Diagnostics.TraceEventType.Information;
Message = message;
CloseLog();
}
}
When we increase the number of worker processes in IIS above 1 the log files are prepended with a unique GUID like this:
068aa49c-2bf6-4278-8f91-c6b65fd1ea3aApplication.log
There are several log files generated by the app all of type "Rolling Flat File Trace Listener"
Is there a way to avoid this?
Originally from: http://ykm001.springnote.com/pages/6348311?print=1 (now a dead link redirecting to a game site):
Known problems
A GUID might be prepended to the filename of the log file
A RollingFileTraceListener instance "owns" the log file it is writing to and
locks it for exclusive write access when it writes the first log entry. It
keeps the file locked until the instance is disposed. If another
RollingFileTraceListener instance is created that points to the same file,
before the first instance is disposed, the second instance cannot open this
file for writing and will write to a new file with a GUID prepended to its
name.
The RollingFileTraceListener indirectly derives from
System.Diagnostics.TextWriterTraceListener. This class changes the filename to
include a GUID when the file with the specified filename cannot be written to.
This is because RollingFileTraceListener indirectly calls the EnsureWriter
method on its base class TextWriterTraceListener. .NET Reflector shows this
code for System.Diagnostics.TextWriterTraceListener.EnsureWriter() in
System.dll (slightly rewritten to improve clarity):
try
{
this.writer = new StreamWriter(fileNameWithPath, true, encoding1, 0x1000);
break;
}
catch (IOException)
{
Guid guid1 = Guid.NewGuid();
fileName = guid1.ToString() + fileName;
fileNameWithPath = Path.Combine(folderPath, fileName );
}
Basically it seems to be a known problem, there is a workaround at
http://entlibcontrib.codeplex.com/workitem/7472
Using the NoGUIDRollingFlatFileListener doesn't help, the problem still occurs (even after much time spent recompiling the logging application block). It might well be fixable in EntLib 4 but I'm stuck with Ent Lib 3.1
Perhaps I should look at alternative logging mechanisms

Sharepoint Webpart custom properties get default values on server reboot

I have noticed that the custom properties of a webpart I developed return to their default values when I reboot my machine.
Is that a normal behavior? are the properties saved as far as the server is up, or there is some parameters I am missing.
Thank you.
EDIT: code:
namespace TestWebpart
{
[ToolboxItemAttribute(false)]
[XmlRoot(Namespace = "TestWebpart")]
public class GraphWebpart : Microsoft.SharePoint.WebPartPages.WebPart
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = #"~/_CONTROLTEMPLATES/Test_Graph/TestWebpart/GraphWebpartUserControl.ascx";
protected override void CreateChildControls()
{
ReloadElements();
}
protected void ReloadElements()
{
Controls.Clear();
GraphWebpartUserControl control = (GraphWebpartUserControl)Page.LoadControl(_ascxPath);
control.xmlDataUrl = XMLFileUrl;
Controls.Add(control);
}
private static string _xmlFileUrl;
[WebBrowsable(true),
Personalizable(PersonalizationScope.Shared),
DefaultValue(""),
Description("xml"),
DisplayName("xml"),
WebDisplayName("xml")]
public string XMLFileUrl
{
get { return _xmlFileUrl; }
set {
_xmlFileUrl = value;
ReloadElements();
}
}
}
}
EDIT2:
Deleting static from the fields throws the flowing exception:
Web Part Error: An error occurred while setting the value of this property: TestWebpart:XMLFileUrl - Exception has been thrown by the target of an invocation.
Hide Error Details
[WebPartPageUserException: An error occurred while setting the value of this property: Blue_Graph.GraphWebpart.GraphWebpart:XMLFileUrl - Exception has been thrown by the target of an invocation.]
at Microsoft.SharePoint.WebPartPages.BinaryWebPartDeserializer.ApplyPropertyState(Control control)
at Microsoft.SharePoint.WebPartPages.BinaryWebPartDeserializer.Deserialize()
at Microsoft.SharePoint.WebPartPages.SPWebPartManager.CreateWebPartsFromRowSetData(Boolean onlyInitializeClosedWebParts)
First of all you should not have
private static string _xmlFileUrl;
it should be
private string _xmlFileUrl;
This static variable will be lost on IISRESET - won't work in a farm and has the potential to cause all sort of 'thread safe' issues if used multi-threaded environment (like a web server) so only use them if they are really needed.
When SharePoint loads a web part (or after you click Save/Apply in the toolpart) it uses reflection to find your properties (the [Browsable... attribute) and then serialization to load/save the value of the property to the database. One of these two is failing.
I would suspect that is some problem with the attribute - try this one and work backwards until it stops working ;)
[Browsable(true),
Category("Miscellaneous"),
DefaultValue(defaultText),
WebPartStorage(Storage.Personal),
FriendlyName("Text"),
Description("Text Property")]

Resources