Shell Integration Library WindowChrome with Drop Shadow - wpf

Ive been googling this alot but can't find any working solution. Im using Shell Integration Library to cerate custom Window Chrome and I also need drop shadows for this window. Some say setting GlassFrameThickness to -1 do the trick but its not working for me. And Jeremiah Morrill suggested using DwmExtendFrameIntoClientArea. Ive tried that and it works, sort of. The shadows looks ok but when the window is shown it is first shown as a glass-frame and then a second later the real content is superimposed. This causes to much flickering for me. Is there any way to get rid of this flickering or is there any better way using only Shell Integration Library?

I had a similar problem where it wouldn't display any shadow when using a custom chrome. It worked fine when using the glass.
I got a shadow by setting GlassFrameThickness="0,0,0,1". The glass didn't show and I got the shadow.
Be warned, the shadow is a simple RECT to Windows, so if you have a funky chrome with transparencies it may look funny.
Also if you support the maximized state be aware the you'll need to set a margin on your top-level panel element of "8,8,8,8" when in maximized mode. All other modes should be "0,0,0,0".
To alimbada, the WindowStyle defaults to None on custom chrome.

The Shell Integration Library uses DwmExtendFrameIntoClientArea, plus handling of several Window messages to get the effects. If you're using the full window rect (i.e. no rounded corners) then setting it to (0,0,0,1) as suggested will give you the drop shadows as you want. If you want to simulate the rounded corners of Aero, then setting it to (8,8,8,8) will extend the glass frame enough that the corners also stay rounded, and then you're responsible for not drawing over the corners of the rectangle. The shape of the drop shadow doesn't change regardless of the glass frame thickness.
The flashing you're seeing when setting the thickness to -1 still exists even when not fully extending the glass frame. What's happening is the window is getting shown while the content is still compositing. What you can do is simplify the default UI so it displays quicker (or you can stage it, bringing in a simnple background first and then replacing it with something usable), or you can create and show the window off-screen, and then move it to the desired start location once the content has been rendered. The easy way to detect when it's probably ready is to invoke a DispatchTimer with Priority=Loaded. That should only get invoked once the basic first layout has been completed.

Related

Why is there a black lag every time a WPF window is resized?

Other questions on SE address how to speed up nested UI control resizing, but- what if there aren't any controls?
As you drag the edge of a WPF window, even a main window with no content, black bars flicker briefly during the drag. This produces a crummy feel- one that I don't want to inflict on customers:
It does get slower and heavier with a full UI on top of it as well. This doesn't even get into how ugly it looks when resizing using the top or left edges. Windows Forms- even with the heaviest UI I've built- never looks this bad right off the bat.
What can be done to make WPF window resizing performance comparable to win forms?
(I have Windows 7 x64 and a triple monitor system on an AT Radeon HD 7470.)
You could update your graphic card and try it out again but that wont change anything. The reason is pretty simple. We all get to see this sometimes based how fast/slow our computer is. Sometimes it runs smooth because we do not have many visuals to draw. The reason is no proper background color is found in graphic card at that moment in redrawing process. Your drivers are fine, and its not just because you use Wpf. Other techniques use the same mechanism behind redrawing.
The first thing WPF will do is clear out the dirty region that is going to redraw. The purpose of dirty regions is to reduce the amount of pixels sent to the output merger stage of the GPU pipeline. Here is where we see the black color. Window itself at that point has no background color or its background color is set to transparent and so to us the GPU draws the black background. Things run async in wpf which is good so.
To fix this you could set a fix color such as "White" to the Window. Then the WPF system will clean out the dirty region but fill it automatically with white color instead of black. This usually helps.
Match the window color or the color of top most layer. Dont let GPU use black and you should do fine. Btw Wpf is faster than WinForm so dont worry.
The look is crummy indeed, especially when using the top or left border.
Which exact problem your screen shot is showing depends on how long your app is taking to render as well as a couple of background related settings that you might be able to tweak to get better resize. Plus part of the ugly resize is specific to Aero.
While I can't address the specific crazy slowness of WPF redraw, I can at least give some insight on why you see black, where that is coming from, and whether you can change to a less annoying fill-in color.
It turns out there are multiple different sources of the black and the bad resize behavior from different Windows versions that combine together. Please see this Q&A which explains what is going on and provides advice for what to do (again, not specific to making WPF faster but just seeing what you can do given the speed you have):
How to smooth ugly jitter/flicker/jumping when resizing windows, especially dragging left/top border (Win 7-10; bg, bitblt and DWM)?

ImageViewer in WPF

Hi everyone I would like to implement an ImageViewer (like the one in Facebook for example) in a WPF application
I already have a ListBox whith my pictures, it works well. But I would like to add pop "image full size" when the user double click on one of them. (something like in FB, with a fade out of the background etc).
Currently I'm thinking of to use a Window...Do you have a better idea of what I should use ?
i would probably use a window for that as well. Then you can easily put an opacity animation when the window loads to give it the fade in and fade out effect
You could also use a Popup control.
It comes with some some built in (but very limited) animations, like fade, see PopupAnimation.
I'd try that and if it doesn't fit your needs, I second bflosabre91 oppionion and would use a separate opacity animated window.
But bear in mind that with an additional window you could have negative side effects e.g always sync the window positions correctly, handle task switches (ie. correctly hide the window in the taskbar/tasklist)

How do I remove the border of a WPF window in the Design view/tab?

I am trying to remove the border of my WPF window in the design view/tab in Visual Studio. Please don't mistake this as a request to create a border less WPF window. I did that and it is working fine. What bothers me is that even if you have set WindowStyle = None, ResizeMode = NoResize, the design view/tab still shows a border around your window in the preview.
Is there a way to remove said border and have a 1:1 preview of the border less window as in Windows Forms?
Every question I have found in regards to this only asks how to remove the border of the actual application. I would like to remove it in the preview.
Any help would be very much appreciated :)
here is a screenshot of my problem:
This cannot be done as this is just how Visual Studio renders a window in design view (I think the frame is probably there so that you can distinguish when you are editing a Window rather than a UserControl).
Rather than try and find a solution to this I would ask myself if this is something I need to be spending time figuring out - after all you say that your program works correctly when being run. I think your time will be better spent writing code for your program rather than trying to play with the design time environment.
Update: In response to you comment, consider that the window frame will be different on every users machine depending on their operating system version (XP vs. Win7) or the theme the user has installed.
My computer has XP installed so the side borders are a lot thinner than those shown in design time so any content will be smaller (but only my a few pixels - 4 in my case; does your user interface design really depend on 4 pixels?).
When using a technology such as WPF you should not be designing your UI to fit to exact pixel sizes; you should be designing with min / max values or using layout containers that adjust to the size of the window as set by the user. Any regions in your UI (E.G. sidebar and main content) should be expressed as a ratio or percentage of one another; instead of saying "The side bar is 150 pixels wide and the main content area is 350 pixels wide" you should be saying "The side bar takes up a third of the window width and the main content takes two thirds".
Although the question is very old and have already been answered (kind of), I just realized: if you set WindowStyle="None", your undesired border is gone.

FlowDocument loses ClearType in child elements when placed in window with custom glass

So the new WPF 4 text rendering looks great, but enabling the aero glass effect on a window requires that you change the background to transparent, which of course disables ClearType rendering.
Using the provided RenderOptions.ClearTypeHint=Enabled allows you to designate child elements to reenable ClearType rendering from that point in the tree. I've found a few other topics that talk about doing this for the ScrollViewer used internally inside RichTextBox and FlowDocumentScrollViewer, and creating a custom style does indeed fix it so that my FlowDocument gets ClearType rendering again.
However, this only applies to top level paragraphs in the FlowDocument. If I add floaters or figures, or a table, any text inside them is inexplicably grayscale again. I know that the glass effect is to blame, since disabling it reenables the ClearType rendering.
I looked through the visual tree with Snoop, but both the main content (which renders properly) and the sub-content (which is grayscale) have similar element hierarchies without anything to which I can attach RenderOptions.ClearTypeHint.
Has anyone run into this problem? Is there a workaround or a solution? I checked Connect but there isn't any bug filed about this. It's quite an annoying problem.
After doing a lot more research, and comparing the way different controls work on and off of aero glass, I've found a few answers. The TextBox control doesn't work properly either, but portions of FlowDocument and things like TextBlock do, which prompted me to explore why.
After digging around in reflector for a while, I found that when using the advanced text formatting APIs to get text and render it onto a drawing context, the RenderOption flags essentially go ignored, since the drawing system knows from the root visual (the window) that transparency was enabled. Once that happens, all the RenderOptions flags in the world aren't going to get ClearType back.
I did happen to stumble on a work-around though. If you have access to the DrawingContext and are doing the low-level text rendering yourself, you can do a DrawRectangle behind the text with a fill, and ClearType gets reenabled. I assume that this is the only way for the renderer to be sure that it has a proper background to draw on.
So in summary, you need to do your own text drawing, and additionally you need to explicitly draw a background using the same DrawingContext behind your text in order for ClearType to get rendered properly.
I know this could get tedious, but have you tried setting general styles like so:
<Style TargetType="Paragraph">
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled"/>
</Style>

Changing the colour of Aero glass for my window?

I'm using DwmExtendFrameIntoClientArea in my WPF application to get the glass effect. This is working fine. What I'd like to do is change the colour used for the glass -- I'm writing a countdown timer, and I'd like the window to be the normal glass colour most of the time, and then to go red (but still with glass) when the time runs out.
I found this question, which talks about how to apply a gradient glass, and that works fine when picking a different colour. Unfortunately, the borders are not coloured appropriately.
When I turn off the borders by using ResizeMode="NoResize", then I end up with square corners. I'd like to keep the rounded corners.
I looked at creating an irregularly-shaped window, by using AllowTransparency="True" and that works fine, but doesn't look like an Aero glass window. It looks a bit flat.
So: my question: how do I create a window in WPF that looks like Aero glass transparency, but uses a different colour?
I think the only possible way to achieve this is to use a semi-transparent filled border and draw it over the entire window or the part you got the glass. Its a workaround but I guess it's a possible solution since the color of the glass gets defined by the system-user and this setting would overwrite yours.
I'm asking the same question myself.
I haven't found a good solution, though the best I've come across so far is doing the following:
HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.FromArgb(100,255,0,0);
Unfortunately this tints the minimize, resize and close buttons, which I would rather avoid.

Resources