33

I am making a application with a borderless window on Windows. However, since the window is borderless, I have no areo shadow, snap, minimization animation, or shake. I have looked around and found no site that explains how to implement this. However, I know it is possible because Office 2013, Visual Studio 2012, and Steam all have these features and are borderless. I am specifically using QT and C++ but if you have solved this for another windowing library I would like to hear your solutions as well. either. And by areo shadow I don't mean drop shadow on two sides, I mean the glowing shadow on all sides of all active native areo windows applications.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
joshua-anderson
  • 4,458
  • 5
  • 35
  • 56
  • 1
    I read up on DWMWA_ALLOW_NCPAINT. So word 2013 and VS2012 draw OVER the boarder to hide it? – joshua-anderson May 27 '13 at 18:06
  • Many people are looking for the answer on this question, as I see. I was one of them a while ago. I tried the implementations, already answered in this post and for reasons they are not fit perfectly. After some time of googling and modifying the deimos1877's BodrelessWindow sample, i ended up with more lightweight solution for Qt. This is simple Qt project with just QMainWindow. Feel free to use and adopt it for your needs. The main advantage is - no proxy classes between Qt window and native WinAPI, no window title flickering through with Aero off. https://bitbucket.org/artem_bodrin/framless – Artem Bodrin Dec 08 '17 at 13:04

3 Answers3

43

After using Spy++ to inspect Steam's window (its window styles, how it replies to window messages) and trying to match everything it does, combined with the DWMAPI calls from this C# borderless window behavior, I believe I figured it out.

To hide the window's border, handle the WM_NCCALCSIZE message in your WindowProc:

case WM_NCCALCSIZE: {
    if (window->is_borderless) {
        return 0;
    } else {
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }
}

To enable the shadow, all you need to do is:

MARGINS borderless = {1,1,1,1};
DwmExtendFrameIntoClientArea(hwnd, &borderless);

To turn it back off, restore the default margins MARGINS windowed = {0,0,0,0};. Perhaps throw in a SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE ); also, to make sure the frame gets redrawn.

However, this does not seem to work with all window styles, apparently your window style must not contain a titlebar. Title bars work fine, and adding one seems to enable the minimize animation.

The simplest window style I got the shadow to work with was WS_POPUP | WS_THICKFRAME, to also get aero snap, maximizing, minimizing, and the smooth minimize animation I used WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION.

Changing DWMWA_NCRENDERING_POLICY or DWMWA_ALLOW_NCPAINT via DwmSetWindowAttribute does not appear to be required, the default settings seem to work.

One word of caution: DwmExtendFrameIntoClientArea does exactly what the name suggests, so if you are drawing an image with an alpha channel directly into your client area (say with opengl, direct3d/2d), a small frame will be visible through it:

borderless window with shadow and frame showing in client area

So you might have to put a non transparent widget, brush or something behind the transparent element.

If all goes well, it should then look like this:

enter image description here

Here is a small example project, F11 toggles borderless/windowed mode, F12 toggles the borderless shadow on and off.

melak47
  • 4,772
  • 2
  • 26
  • 37
  • Steam still has a shadow identical to that of Aero. It has Aero Snap/Shake/Stuff too, but lacks a minimize animation. – Keavon Jul 18 '13 at 04:20
  • @RandomUser My solution does everything except the minimizing transition - a result of the window style required to make the shadow work. Even Outlook 2013 lacks this, so I do not believe it is possible without faking it like Visual Studio does its glows. (sometimes you can see the window frame becoming visible inside the "client" area - so they do indeed appear to draw over the frame) – melak47 Jul 21 '13 at 11:10
  • Visual Studio's minimize animation seems to look exactly like a window with a border. Did they just do a really good job faking it? Any idea how we could go about faking it as well? – Keavon Jul 25 '13 at 02:40
  • It looks that way. I think it'd be a lot of effort just to get the minimize animation, though - you won't get the aero shadow; you'll have to draw [your own shadow/glow](http://msdn.microsoft.com/en-us/library/windows/desktop/dd145212(v=vs.85).aspx) instead of the frame. Also, there could be lots of special cases to handle to maintain the deception of the border not being there. Say, making sure that Alt+PrintScreen only captures the client area and not the frame, window size for aero snap (so there is no gap because of the see-through border)... – melak47 Jul 25 '13 at 09:14
  • Everything except the minimize animation, I think. – melak47 Aug 30 '13 at 06:05
  • @melak47 I can't seem to get this to work, can you please upload your project files so we can see this in action. That would be really helpful Thank you so much. – Mathew Kurian Sep 13 '13 at 07:06
  • @Keavon I was wrong about the title bars, if you add `WS_CAPTION` to the style you will get the minimize animation as well. – melak47 Sep 13 '13 at 14:54
  • @melak47 Thank you so much! I have tried running it on VS2013 RC and has some small issues. So I went ahead and opened an Issue on Github and we can hopefully continue this conversation there. – Mathew Kurian Sep 13 '13 at 16:12
  • @melak47 Do you mind if we use some of your example code (For Now) in our open source application? – joshua-anderson Sep 20 '13 at 23:40
  • @joshua-anderson not at all :) – melak47 Sep 22 '13 at 14:10
  • @melak47 I got it worked :) But I can't see the control buttons. does it come with the titlebar itself ? Can I show the control buttons with those configurations ? – Morpheus May 30 '14 at 07:24
  • @Morpheus there was some window style which would show the buttons even in borderless mode, check the comments in my code where I define the styles. they don't look pretty though, you'd be better off drawing your own. – melak47 May 30 '14 at 07:37
11

Thanks to melak47 for your answer.

For people whom are looking for a C++/Qt example, this GitHub profect does the job like a charm (thanks to deimos1877) based on melak47 code! https://github.com/deimos1877/BorderlessWindow

Be sure to use visual studio compiler (>= 2010) to get the needed DLL and it should work. This example include aerosnap support, borderless window, minimize effect, aero shadows.

Kévin Renella
  • 1,007
  • 9
  • 20
  • 2
    I'd like to say, this is the best answer, hope new people comes to here to use this demo. – lygstate Oct 28 '14 at 15:32
  • 1
    With Qt5.8 you get a compiler error in `qwinhost.cpp` in line 257 complaining about not found `qWinAppInst()` identifier. `qWinAppInst()` has been removed from QtCore in Qt5.8 (see [here](https://github.com/qtproject/qt-solutions/commit/master)) so you have to replace that one with `GetModuleHandle(0)` – user2366975 Apr 04 '17 at 17:22
2

I have created one that responds as photoshop.

BorderlessWindowQt-Modern-Gui

Image True Borderless WindowQt

Ripi2
  • 7,031
  • 1
  • 17
  • 33