I am trying to get the current Windows theme name in C# but it has turned out to be a little tougher than expected. I have a code sample from MSDN:
public void Test()
{
StringBuilder themeFileName = new StringBuilder(0x200);
GetCurrentThemeName(themeFileName, themeFileName.Capacity, null, 0, null, 0);
string fileName = Path.GetFileName(VisualStyleInformation.ThemeFilename);
if (string.Equals("aero.msstyles", fileName, StringComparison.OrdinalIgnoreCase))
{
// user is using aero theme
}
}
[DllImport("uxtheme.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentThemeName(StringBuilder pszThemeFileName, int
dwMaxNameChars, StringBuilder pszColorBuff, int dwMaxColorChars,
StringBuilder pszSizeBuff, int cchMaxSizeChars);
GetCurrentTheme() does not modify the StringBuilder. I also tried looking at the
System.Windows.Forms.VisualStyles.VisualStyleInformation class, but it is full of empty values. Anyone know how to do this? I must be missing something easy, but I haven't found anything yet that works.
That article on CodeProject describes how to get "the current visual style information" (search for that string in the article).
It contains sample code how to do that.
You are not passing the string builder by reference.
Related
I try to load an image from imgres32.dll. I'm trying to do it like this:
Load the dll:
dll_h = LoadLibrary(#"C:\Windows\System32\imgres32.dll");
Pass the handle to my function which does the ressource loading:
Bitmap b = GetImageResource(dll_h, "1002");
The function looks like this:
static Bitmap GetImageResource(IntPtr handle, string resourceId)
{
IntPtr img_ptr = NativeMethods.LoadImage(handle, resourceId, IMAGE_BITMAP, 0, 0, 0);
if (img_ptr == IntPtr.Zero)
throw new System.ComponentModel.Win32Exception((int)NativeMethods.GetLastError());
return Image.FromHbitmap(img_ptr);
}
No matter which parameters I enter, I always get error code 1813 meaning
The specified resource type cannot be found in the image file.
When I open the file in Visual Studio, I see a folder called Icon containing an Image with id 1002.
When I click it, it shows me several Bitmap images contained, in different resolutions, containing one with resolution 16 x 16. But when I call
LoadImage(handle, resourceId, IMAGE_BITMAP, 16, 16, 0);
Neither this not any other parameter combination does work, I always get error 1813.
IMAGE_BITMAP is a constant int set to 0 like documented here, same with IMAGE_ICON and IMAGE_CURSOR but none of them works.
Help is very much appreciated. Thanks.
You should prefix the resource Id with #. Call it this way:
GetImageResource(dll_h, "#1002");
I'm trying to replicate the following from the Event Viewer:
I'm having trouble with a few things.
Some of the names I get back are not the display names or friendly names. For example, for "Microsoft Office Alerts" I just get back "OAlerts". How can I get the full "Microsoft Office Alerts" from "OAlerts"?
Figuring out the hierarchy. It seems all I can do is parse out the dashes and do some sort of a best guess. There doesn't seem to be an easy way in the API to figure it out. The GetLogNames just gives you a flat list of all the logs
EventLogSession session = new EventLogSession();
List<string> logNames = new List<string>(session.GetLogNames());
foreach (string name in logNames)
{
//EventLogConfiguration config = new EventLogConfiguration(name); //looks useful but doesn't give me any of the info i'm looking for.
Console.WriteLine(name);
}
This blog here: The EventSource NuGet package and support for the Windows Event Log (Channel Support) has a link to a rare EventSource User's Guide document that states this:
Do use the EventSourceAttribute’s Name property to provide a
descriptive, qualified name for the ETW event provider represented by
your event source. The default is the short name of your event source
type, which can easily lead to collisions, as ETW provider names share
one machine-wide namespace. An example of a good provider name
“<CompanyName>-<Product>-<Component>”. Following this 3-element
convention will ensure Event Viewer displays your event logs in a
logical folder hierarchy: “Application and Services
Logs/<CompanyName>/<Product>/<Component>”.
Which tends to indicate the dashes are more a convention than a strict requirement (So I believe you can parse it by yourself). Note the blog is still open for comments.
As for names that don't match, there is an undocumented EvtIntGetClassicLogDisplayName function that can get you the name displayed in Event Viewer. Here is how to use it with a session and a log name:
static void Main(string[] args)
{
var session = new EventLogSession();
foreach (string name in session.GetLogNames())
{
Console.WriteLine(GetDisplayName(session, name));
}
}
And here is the support code (since it's undocumented, use at your own risks, plus it seems to be useful mostly for this 'OAlert' entry, so I'm not sure it's worth it):
public static string GetDisplayName(EventLogSession session, string logName)
{
var sb = new StringBuilder(512);
int bufferUsed = 0;
if (EvtIntGetClassicLogDisplayName(GetSessionHandle(session).DangerousGetHandle(), logName, 0, 0, sb.Capacity, sb, out bufferUsed))
return sb.ToString();
return logName;
}
private static SafeHandle GetSessionHandle(EventLogSession session)
{
return (SafeHandle)session.GetType().GetProperty("Handle", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(session);
}
[DllImport("wevtapi.dll", CharSet = CharSet.Unicode)]
private static extern bool EvtIntGetClassicLogDisplayName(IntPtr session, [MarshalAs(UnmanagedType.LPWStr)] string logName, int locale, int flags, int bufferSize, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder displayName, out int bufferUsed);
I am having some difficulty in loading a font from a resource into PrivateFontCollection.
When I started this, I was successful in loading the font from a file, however I wish to embed the font into my project (so there is less file mess on the user side, and a bit less IO while the application is running).
The following code will load the font, gets the proper name, and allows for scaling however none of the characters are showing up properly.
static class Foo {
public static string FontAwesomeTTF { get; set; }
public static Font FontAwesome { get; set; }
public static float Size { get; set; }
public static FontStyle Style { get; set; }
private static PrivateFontCollection pfc { get; set; }
static Foo() {
// This was set when loading from a file.
// FontAwesomeTTF = "fontawesome-webfont.ttf";
Style = FontStyle.Regular;
Size = 20;
if ( pfc==null ) {
pfc=new PrivateFontCollection();
if ( FontAwesomeTTF==null ) {
var fontBytes=Properties.Resources.fontawesome_webfont;
var fontData=Marshal.AllocCoTaskMem( fontBytes.Length );
Marshal.Copy( fontBytes, 0, fontData, fontBytes.Length );
pfc.AddMemoryFont( fontData, fontBytes.Length );
Marshal.FreeCoTaskMem( fontData );
} else {
pfc.AddFontFile( FontAwesomeTTF );
}
}
FontAwesome = new Font(pfc.Families[0], Size, Style);
}
private static string UnicodeToChar( string hex ) {
int code=int.Parse( hex, System.Globalization.NumberStyles.HexNumber );
string unicodeString=char.ConvertFromUtf32( code );
return unicodeString;
}
public static string glass { get { return UnicodeToChar("f000"); } }
}
Example usage :
label1.Font = Foo.FontAwesome;
label1.Text = Foo.glass;
This is what it looks like loading from memory:
This is what it look like loading from file:
I am using the current FontAwesome TTF file in both the embedded resource and the file based tests. It seems that when embedded something is being lost or scrambled in the translation or when loading from embedded. I need help making this work so I can load the font from an embedded resource into PrivateFontCollection.
There are a few 'solutions' I looked at on SO however they are quite dated and some or all of the commands/accessors are no longer available in Visual Studio 2013 (article solution was from 4-5 years ago). Some example 'solutions' and why they don't work:
Solution #1 - This doesn't work as the accessor string for the font returns null. In my case, the accessor is MyProject.Properties.Resources.fontawesome_webfont
Solution #2 - This solution came the closest, but again the method used to access the resource no longer works. My code above implements a harvested version of this taking out the core concept of passing the byte[] array into memory and then loading from memory. Since the get{} property of the resource in my case returns a byte[] array already, there was no need to 'convert' it into a byte array and thus I was (seemingly) safely able to remove that portion of the code by updating it to use the newer accessor.
In either case, I would like a solution for this problem that allows me to load the font file from the embedded resources into PrivateFontCollection.
I am trying to display a Security Success Icon (with the blue background) in TaskDialog message box. This is not one of the enum values of TaskDialogStandardIcon. Reference: http://dotnet.dzone.com/articles/using-new-taskdialog-winapi.
How do I assign these non standard values to ((TaskDialog)sender).Icon ? Is it even possible in C#? C#
Any pointers would be really helpful.
Regards,
Ashwin
I think you will need to import TaskDialog function from comctl32.dll yourself:
static class TaskDialogWrapper
{
[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
static extern int TaskDialog(IntPtr hWnd, IntPtr hInstance, string pszWindowTitle, string pszMainInstruction, string pszContent, TaskDialogCommonButton dwCommonButtons, IntPtr pszIcon, out IntPtr pnButton);
public static TaskDialogCommonButton Show(IntPtr handle, IntPtr instance, string title, string instructionText, string content, TaskDialogCommonButton commonButtons, TaskDialogCommonIcon commonIcon)
{
IntPtr resultButton;
if (TaskDialog(handle, instance, title, instructionText, content, commonButtons, new IntPtr((int)commonIcon), out resultButton) != 0)
throw new InvalidOperationException();
return (TaskDialogCommonButton)resultButton;
}
}
[Flags()]
enum TaskDialogCommonButton
{
Ok = 0x1,
Yes = 0x2,
No = 0x4,
Cancel = 0x8,
Retry = 0x10,
Close = 0x20
}
enum TaskDialogCommonIcon
{
ShieldGrey = 65527,
ShieldOk = 65528,
ShieldError = 65529,
ShieldWarning = 65530,
ShieldBlue = 65531,
Shield = 65532,
Information = 65533,
Error = 65534,
Warning = 65535,
}
To use your own icon from a file, you will need to import TaskDialogIndirect.
(Btw., I found many other interesting icon styles for TaskDialogCommonIcon. You could add e.g.:
enum TaskDialogCommonIcon
{
None = 0,
Sheet = 2,
ExplorerFolderOpen = 3,
ExplorerFolderFlat = 5,
ExplorerFolderLeft = 6,
Search = 8,
ExplorerFolderClosed = 10,
ExplorerGames = 14,
Application = 15,
TransparentSpace = 17,
ExplorerSearch = 18,
TextFile = 19,
Letter = 20,
Picture = 21,
Diashow = 103,
// ...
}
I know that this is an old question, but I was looking for something similar, so I thought I'd pass along what I've found. Using the information posted by #KnorxThieus, I found a way to use the "hidden" security icons in the TaskDialog without going through the DLLImport process outlined above. Using the actual values he provided for the TaskDialogCommonIcon enumeration, I found that you can simply cast them to the appropriate type (i.e., the TaskDialogCommonIcon), and your application should display them properly.
Please note, I'm using the WindowsAPICodePack version 1.1.2 from Nuget (nuget.org/packages/WindowsAPICodePack-Core), and the code below has been converted from Visual Basic using the Telerik Code Converter (http://converter.telerik.com/), so it's possible that you may have to do some fine-tuning in C#:
if (TaskDialog.IsPlatformSupported) {
using (TaskDialog dialog = new TaskDialog()) {
dialog.Caption = "TESTING";
dialog.InstructionText = "THIS IS A TEST";
dialog.Text = "This is a test of casting a value to the desired Icon type for a TaskDialog.";
// Produces the green shield with green background
dialog.Icon = (TaskDialogStandardIcon)65528;
dialog.OwnerWindowHandle = this.Handle;
dialog.Show();
}
}
In my testing, this seems to work for all of the enumerations #KnorxThieus listed, as well as several others. I'm trying to figure out if there's a similar method for setting the Icon property to another (non-standard) image file, but I've been unsuccessful with that so far. I hope this helps anyone that stumbles across this in the future.
Take a look at the Ookii.Dialogs. It implements the TaskDialog and others dialogs as well, and have versions targeting WPF and Windows Forms.
Hello I have been having issues with MonoGame when building I get the glbind... error in the opengl32.dll so I was suggested to find my GUID and it sounds like a simple task but i have looked in the project folder files and cant find it I found one which is
<ProjectGuid>{325BCA73-8459-49AF-9C31-D4A268BF8A1A}</ProjectGuid>
but im looking for one like this
<ProjectTypeGuids>{9B831FEF-F496-498F-9FE8-180DA5CB4258};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
here is a image of my file folder and the main "collisions".csproj file where I found the one GUID. I have done some research but i cant seem to find an answer as to where to look.
HERE
More accuretly im looking for the Projecttypeguids so I can delete one of them to see if that solves my problem as suggested here....I recognized what i worded at the top is kind of vague sorry
Here
The first example you gave is the GUID of your project. Hence ProjectGuid.
The second is a list of the GUIDs of the project types of your project. Hence ProjectTypeGuids.
If you are looking for the GUID of your project, the first example is giving you the correct answer.
The screenshot you linked to shows a project that does not have any type GUIDs listed. If present, the value is mostly used by development tools (e.g. VS uses it to figure out what items to include in the context menus for adding new items.) If there is no project type GUID your project will still "work" for the most part, but you will likely encounter odd behavior in your IDE of choice.
The project type GUID values in your question are correct for a project that is a C# application that uses the MonoGame plugin. If your project file is missing that tag, just add it yourself with whichever GUIDs you want your project to have.
(The list of well-known GUIDs can be found here, though the MonoGame one I had to look up on Google.)
First you didn't mentioned what you're using winforms or wpf.
OK whatever.The ProjectTypeGuids is not supported in winforms you can find them if you're using wpf.
If you're using wpf you can use this code:
public string GetProjectTypeGuids(EnvDTE.Project proj)
{
string projectTypeGuids = "";
object service = null;
Microsoft.VisualStudio.Shell.Interop.IVsSolution solution = null;
Microsoft.VisualStudio.Shell.Interop.IVsHierarchy hierarchy = null;
Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject aggregatableProject = null;
int result = 0;
service = GetService(proj.DTE, typeof(Microsoft.VisualStudio.Shell.Interop.IVsSolution));
solution = (Microsoft.VisualStudio.Shell.Interop.IVsSolution)service;
result = solution.GetProjectOfUniqueName(proj.UniqueName, hierarchy);
if (result == 0)
{
aggregatableProject = (Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject) hierarchy;
result = aggregatableProject.GetAggregateProjectTypeGuids(projectTypeGuids);
}
return projectTypeGuids;
}
public object GetService(object serviceProvider, System.Type type)
{
return GetService(serviceProvider, type.GUID);
}
public object GetService(object serviceProviderObject, System.Guid guid)
{
object service = null;
Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider = null;
IntPtr serviceIntPtr;
int hr = 0;
Guid SIDGuid;
Guid IIDGuid;
SIDGuid = guid;
IIDGuid = SIDGuid;
serviceProvider = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)serviceProviderObject;
hr = serviceProvider.QueryService(SIDGuid, IIDGuid, serviceIntPtr);
if (hr != 0)
{
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
}
else if (!serviceIntPtr.Equals(IntPtr.Zero))
{
service = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(serviceIntPtr);
System.Runtime.InteropServices.Marshal.Release(serviceIntPtr);
}
return service;
}
it's from here