HOWTO: Get the conditional compile symbols defined in the project for a source file (ITextView) in a Visual Studio Extension
Monday, August 31, 2015Fortunately the Visual Studio SDK provides a way at these values. Unfortunately, it's not as straight forward as I would have liked.
Conditionals given an ITextView
Here's a quick extension method I whipped up to pull the "defines" out of the project file given an ITextView/IWpfTextView.
private static IEnumerable<string> Conditionals([NotNull] this ITextView textView)
{
if (textView == null) throw new ArgumentNullException(nameof(textView));
// Get the text document from the text buffer (if it has one)
ITextDocument textDocument;
if (textView.TextBuffer.Properties.TryGetProperty(typeof (ITextDocument), out textDocument))
yield break;
var componentModel = ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel)) as IComponentModel;
// Get the VsServiceProvider
var vsServiceProvider = componentModel?.DefaultExportProvider?.GetExportedValue<SVsServiceProvider>();
if (vsServiceProvider == null) yield break;
// Get the DTE ...
var dte = (DTE) vsServiceProvider.GetService(typeof (DTE));
ProjectItem projectItem = dte.Solution.FindProjectItem(textDocument.FilePath);
Configuration activeConfiguration = projectItem?.ContainingProject?.ConfigurationManager?.ActiveConfiguration;
var defineConstants = activeConfiguration?.Properties?.Item("DefineConstants")?.Value as string;
if (defineConstants == null)
yield break;
// DefineConstants entries are listed semicolon and comma delimiated, so we need to split on both.
string[] constantSplit = defineConstants.Split(new[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in constantSplit)
yield return item.Trim(); // They can contain whitespace on either end, so we'll strip 'em.
}
Of course, you could get some of those services via an Export and eliminate the GetService / GetExported value calls, but I thought I'd include them since I don't know what you've decided to get from MEF.Have a lot of fun!
Stay Frosty Visual Studio Extension - Method Block Highlighter, Text Clarity, Background Images and a lot more...
Sunday, August 30, 2015For the most updated information, visit the release page
It's hard to believe but I've been working on this extension for almost a year. That's what happens when you only have a few hours every weekend and the occasional evening to work on a personal project. It started out with a simple desire to add a chiseled effect to the text displayed in Visual Studio. I used to get horrible migraine headaches and that little effect made text visibility at low contrast much better without having to change my syntax highlighting rules. A little later I decided I hated being tied to my multi-monitor setup just to be productive when writing software. So I started working exclusively from my laptop screen, a nice 1920x1080, but still not as nice as having a few portrait 1080P displays and a primary 2K, but with a little bit of a change in how I worked (mostly just getting used to some features I never had needed with unlimited real estate), I was easily as productive on my laptop screen. The advantages of changing scenes means I can work when I feel an inspiration; no more having to tuck myself into a room.
Features
Most of the features of Frosty were designed with two purposes in mind: (1) Make working with code in limited screen real estate easier and (2) Make my environment prettier. Both are quite subjective and I don't expect everyone to agree with my decisions ... in fact, I wrote this for me, so if I'm the only user, I'll still be happy!Method Blocks
Methods are highlighted with configurable colors, Static, Instance and Constructors. I decided against making those colors configurable in Fonts and Colors because I wanted to be able to control alpha on each, so I've done it via its own Options panel with a color picker. Sure, methods should be small enough to easily visually parse the beginning and end, but we're not always given the privilege of modifying code we've written. By default, constructors are bright, instance methods are dim and static methods are somewhere in between. I'm always looking to get back to a constructor, so I made it stand out a bit. In a God Object or a method that does too much (that, of course, *I* didn't write! :o) ...), finding important bits is easy.Method Signatures
When the method signature scrolls off the top of the display, it shows up on the left hand side next to the box around the method. Sure, that's available from the drop-down at the top, but my caret isn't always in the method I want to know about. Now it's right in front of me.Text Rendering
Text rendering in the editor window is also configurable. Much like the great extension, TextSharp, except I only apply the effect to the text editor window (no reason for this other than that I didn't need the rest). You can enable ClearType or kill it, along with other things WPF allows you to tweak that Visual Studio doesn't give you direct control over.Chiseled Text Effect
It's off by default. This was the original feature that I wanted, but getting it working turned into a several month long adventure with HLSL. Unfortunately, it doesn't render properly in Visual Studio 2015 without Hardware Rendering enabled. The effect is touchy. Colors need to have a bit of grey in them to render and different colors render slightly higher or lower on the baseline. It's a bug I intend to fix, but for now consider it quite "alpha" in nature. That's life!Configuring
Go to "Stay Frosty" in "Tools|Options". You'll find it *highly* configurable. I like ultimate control over my environment so I tried to leave nothing out as far as customization. Maybe you don't like the features I've implemented? Turn 'em off or change them! Sure, software should be opinionated,... except when its users are developers.License
I'm not ready to release the source code quite yet, but I will be. The extension is licensed under the Apache 2.0 license. I had to learn quite a bit about Visual Studio Extension development over the last few months and I'm hoping that my experiences with it will help others, so I'm separating out parts into their own projects that can be used by others as utility libraries. Right now, time is keeping me from completing that part, plus I'd like to get a little more feedback from testing in the wild before I throw that out there.Compatibility
At the moment Frosty supports Visual Studio 2013 and Visual Studio 2015. I'm using the awesome NRefactory library for code parsing in Visual Studio 2013. The 2015 version, of course, uses Roslyn and as a result performs a bit better than the 2013 version. Since I started with 2013, I didn't want to abandon that work and all of the folks who are stuck on the old version.Caveats - It's Beta
It's beta. If you run into difficulties, please let me know at matthew dot dippel at google's public e-mail service. I'd love to get it right and working. If you want to help out, I'll have the code out on GitHub soon!There's (at least) one bug. The signatures don't always disappear from the left hand side when the top of the method becomes visible again when scrolling up. And it does use some additional resources when parsing code on Visual Studio 2013 -- it shouldn't get in the way too much on a decent machine (it performs well on my Core i5)
Updates from Initial Feedback
If you use ReSharper (I do!), you can enable their syntax highlighting rules (disabled by default, enable them in options).You can now enable the Method Signatures to display regardless of whether or not the method signature is scrolled off screen (disabled by default).
Abstract methods are no longer bordered.
Two libraries were removed in favor of the PresentationFramework equivalents.
The error that some were seeing when visiting the options page might be fixed. (I'm not seeing this on my machines)
If ReSharper or the User Classes/Enums/etc Fonts and Colors option is missing, we'll use Identifiers instead of Plain Text.
Fixed an exception that occasionally happened on file load where the width of the adornment would be calculated to a negative number.
Fixed the caching of method signatures so they wouldn't have to be re-created every time they were drawn.
Download the Visual Studio 2015 Edition
Download the Visual Studio 2013 Edition
Quick Fix: Could not load file or assembly when instantiating XAML component (or IoC component) in a Visual Studio Extension Project
Wednesday, July 22, 2015Symptom
You're writing a Visual Studio extension that involves some XAML or IoC code that references a DLL file. When you attempt to instantiate the control, the debugger pops up with "Could not load file or assembly". You've checked the Fusion log and notice it isn't looking in the folder that contains the extension!Fix
Add the attribute [ProvideBindingPath] to the class that represents the package (the class that implements the Package base class which is often completely empty).Why?!
Visual Studio's Extension engine usually figures out where your reference .dll's are and binds them easily, however, when a .dll is referenced in XAML or IoC, it isn't explicit enough for Visual Studio to handle proper binding. The ProvideBindingPath attribute tells the extension engine to look in the extension folder when attempting to resolve dependencies. In my case it was a fancy options page that used XAML for its UI rather than the automatically generated UI.Stay Frosty Extension Preview - A WPF ShaderEffect for chiseled or beveled text
Saturday, June 27, 2015Stay Frosty
There's always been a retro movement in the programming world. Every time a new tool comes out that reduces the requirement to memorize commands or the complete API of a language, there's many among us who wish we had a green terminal and punch cards. The elite look down upon us folks who love Visual Studio, spouting off about the advantages of vi/vim, emacs and other ancient, though powerful, tools. I came from that era. Screw it. I like my Intellisense and GUI based IDEs. I like defaults that build (most of the time). I like using a keyboard shortcut to fire the whole thing off in a debugger and I enjoy a gargantuan 32-bit text editor.I use many text editors for lighter-weight work. Sublime is awesome, as is the atom.io editor I'm starting to fall in love with. But my primary language for work and play is C# and Visual Studio has the tooling I need for that work. And if you're going to use a GUI interface for text editing, it might as well be really, really Gooey!
For the last 4 years or so, I've had an extension I wrote for myself to add a simple background graphic to the text editor window. I wrote it for Visual Studio 2010, originally, and since that time there have been many others that do the same thing. I decided late last year to take it a step further.
What, precisely, are you trying to fix?
I used to get Migraine headaches regularly. I had tried triptans (and found out that my body does not metabolize them correctly) and many other medicines. None worked. Thankfully that's in the past, now, but prior to last year I had to figure out how to live my life and do my job while dealing with a very intense headache. I've never let Migraine keep me from living my life. Unfortunately, displays of any kind seem to trigger the worst sensitivities. My only trick was to work in a dim room with the Brightness setting on my display turned down. Unfortunately, many colors become invisible as the brightness drops. My options were limited, so I used the Visual Studio Color Theme Editor extension to keep two themes, one titled Migraine and one titled Normal. The Migraine theme had most of the syntax rules set to the same color, and all of the text was very, very bright. It was not ideal for using day-to-day but it worked when I needed it.Sometime around 2011 I purchased an 27" iMac. At the time it was the least expensive IPS display at its resolution and it had the added benefit of having a Mini-Display Port plug on the back that would allow you to plug in an external PC. I used it as my monitor and rarely logged into OS X. I did, of course, download XCode and all of the Apple development environment tooling. One morning I woke up with the familiar headache symptoms and began work in my home office. The Windows box had shut down and I was left on my Apple screen, so I powered up the PC and logged into my Mac to waste away the boot time on the web. The last time I had logged in I had left XCode (I think that's what it was) up. I noticed immediately that at the lowest display setting, all of the text was readable. The principal reason for this was a very subtle text chiseling applied to the code editor window. This got me *very* excited -- I could code using my normal syntax highlighting and still read the text at low brightness! A quick look around though spoiled my excitement. There was no ShaderEffect to be found that could apply this chisel. I'd have to write my own. And I'd have to write it in a language that I was unfamiliar with. Having too much to do already, I put it down until late last year.
A Mac-like Chisel Effect
The brilliant folks in Cupertino did something rather simple. The effect was no more than a subtle glow on the bottom and shadow on the top. Surely this couldn't be difficult to reproduce. It turns out, in the end, it wasn't all that difficult. I am not a game developer. I've never written a line of shader code. While I am plenty familiar with C and comfortable with the math, I found myself in hell without a debugger. Something so straight-forward was complicated by subtle requirements WPF imposes on ShaderEffects. Multipass? Nope. Alpha that works like the rest of the libraries I was familiar with? Nope. It's pre-multiplied. I was amazed at the body of knowledge I had to immerse myself in to write a simple ShaderEffect for 2-dimensional text. I wanted, after all, a pixel above and a pixel below the boundaries of the font. I was up against ClearType, DirectX and the fact that in the realm of 3D the concept of a pixel is absent, and of course, GPU parallelism. Fun.The Stay Frosty Extension
The title is a bit of a joke. I got a chuckle out of Scott Hanselman's comment in the first paragraph of his Visual Studio Programmer Themes blog post and thought I'd swipe it.The main purpose of the extension is to improve code text readability. WPF has long had a lot of complainers about how it render text. In the version used by Visual Studio 2013, you can tweak the text with several rules around font smoothing, hinting and rendering as well as requiring that the output snaps to the pixels of the device that's displaying it. I've exposed these as settings. You can apply rendering, font smoothing and hinting rules as well as require text to snap to device pixels. I've tweaked the window to allow the placement of a background image and an override to the background color without requiring the aforementioned Theme Editor extension installed (and it'll override whatever theme you've put there, as well). In addition, you can (optionally) apply the ChiseledText ShaderEffect and control the settings around it (described below). I plan to add many, many more capabilities to it and it will be released under the Apache 2.0 license as well, however that's my planned first release.
Here's how it looks in my environment fully customized: The image above shows the effect at about 50% which is where I like it.
The ShaderEffect
You can download the library complete with the HLSL source and the ShaderEffect class implementation from its BitBucket repo. The effect is simple but could still use some tweaking. It's "good enough" at the moment, but if you have any improvements, I'll gladly accept them!How it works
Very loosely, it works by layering a darkened and lightened version of the input offset by the size supplied in the size parameter. That's not really how it works, but that's how it appears to work when you use it. In addition to the two layers, the original sampled pixel is mixed in so that parts of the font aren't wiped out as the shadow and glow are offset. Due to pre-multiplied alpha and some blending, the main part of the font remains identical to the input color and the glow/shadow are lighter and darker. As I said, it's very simple.Usage and Limitations
Reference the library and add the effect to any text element. It'll work with other elements, but the results may not be all that great. I designed it to work with small text since it was aimed at the code panel in Visual Studio but it works fine on large text, as well, provided you tweak the effect settings accordingly. The effect is applied vertically, only. It would be easy to change to allow an angle specified and, in fact, the earliest working prototype I had did this, however it nearly doubled the instruction count and performance suffered. I wanted this thing to work well with software rendering and to be as inexpensive as possible, so that's a trade-off I took and it's the other reason it will start to look less than ideal with large text.- Size - This is the size (roughly) in pixels of the effect. This is really the offset of the two layers. The glow layer is usually far more visible than the shadow layer so changing this might have the illusion of only increasing the glow portion of the effect. It's a double, so any fraction is fine. If you use a negative number, the chisel will appear as a bevel. The ideal value will vary depending on the target size of the text. The effect above uses a value of 0.5f which is also the default.
- GlowIntensity - This increases the intensity of the glow portion of the layer. Remember that the actual color is just a combination of glow and shadow, so increasing the glow will similarly increase the overall brightness of the font, too. Sorry about that. The default value for this is 1.0f
- ShadowIntensity - Same as Glow, but for Shadow. If Glow and Shadow are the same value, the font in the middle should be about the same color as the input.
- MixDivisor - It's a terrible name and I will be changing it. At the end of the HLSL, the input pixel and the new values calculated for the two layers are divided by this number. 3.0f is the default and causes the text to barely blend with the background. Increasing this value will make the text and the effect blend more with the background. Use the Intensity and this value together to get the desired result. The text in the picture above uses a value of 3.5 on a background of #FFAAAAAA.
I also strongly recommend a font with some meat on it. Mac OS renders fonts differently than Windows. They're chunkier and cleaner. Google mactype if you want similar results in Windows, or use a very high-quality OTF font. I use Source Code Pro Medium, free from Adobe, and it works quite well. I'll write up some more later explaining the effect in detail. I won't waste much time on the C# code required to use the shader, it's very simple.
As far as the Stay Frosty extension, I'm writing it in some very limited free time. It's nearly done except for a few issues around settings that I'd like to sort out.
You can download the entire library with its code from its public BitBucket repo. It has the path to fxc.exe hardcoded in the pre-build. You'll need to ensure you have the Windows 8 SDK or the DirectX SDK and you'll need to modify the path accordingly. That was a time trade-off for me.
Reliving the Past - The Visitor Access Kiosk
Monday, May 11, 2015Before this sounds horribly boastful
This project was a defining moment for me as a developer. I had, up to this point, been mostly focused in Web/Database applications that were used internally. I had quite a few wins in this area, but nothing that ever extended beyond the walls of the company (beyond a project a few years ago that was sold to a vendor of ours whilst we were in the throws of Bankruptcy).Stupidly, I had never thought to just "google it". At the time, Global Crossing didn't put videos on YouTube, and I'm not entirely sure how it even got there. It was a *monumental* task and I was *not* the right developer to be doing it, but I love code and I love solving hard problems (from time to time). In this case, the VP of our department (an awesome guy who's name I'm omitting because I haven't asked for his permission), asked if I could create a kiosk that would allow a visitor to contact someone in the office from a secure visitor lobby, have a video/voice conversation with them (one way video, inbound to the employee only), would print a one-day-use badge with their picture, name and relevant information and give them a way to sign out when their visit was over. This was to replace the need for a dedicated receptionist, or a pen/paper log-book.
Some implementation details
Unfortunately, the only copy of the original whitepaper has been removed from Microsoft's site -- it was for Office Communicator 2007 R2 (technically we ran it on this version, but it was developed targeting the pre-release of R2), so I'll include that hereI implemented it as a WPF application, touch-only (at a time when a 1024x768 SAW touch screen was $1500). I used a barcode scanner, a simple label printer attached to a USB -> Ethernet device, a Logitech camera, and a ThinkCenter PC running Windows XP (stripped of everything unnecessary, including the Explorer shell. All of the code was my work (that's a statement of fact, not pride -- I would be embarrassed by that code today). My good friend and former coworker George Morell and I handled the operating system hardening -- when you have a guy at your disposal that can tell you the location of every obscure OS registry setting from Windows 2000 to Windows 8.1, you defer to that incredible expertise. And our security guys did some network hardening to ensure that if someone took a sledgehammer to the device and grabbed its ethernet port, it'd be worthless to them.
Most of the application was written in C# (.Net 3.5, I think, I remember thinking ... "generics?" ... like "templates in C++?"... no ... not exactly) with some bits in C and one really nasty bit in C++ (it was the camera interface). It was not a difficult thing to write, but at the time, it was a difficult thing fore me to write.
Without further ado, the Visitor Access Kiosk.
I had to laugh while watching it. The UI is comical today, but keep in mind that this was developed at a time before Windows 7 was released. Windows Vista and Windows XP's "chrome" were the inspiration behind the design. And I had some fun with XAML.
Subscribe to:
Comments
(
Atom
)



