Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you make a Borderless Application Main Window in Windows, without WS_POPUP style?

I want to create a window that will be the main window and that Windows itself recognizes as a main application window. However, when I make my window borderless, and without any non-client area at all, Windows no longer recognizes that this window is an application main window. This has several side effects:

  1. WindowsKey+M minimizes all windows except my application's main window.

  2. Clicking once on the taskbar (in win7) and then again, should toggle the application main window's state/visibility between normal and minimized state. This does not work for such a window.

In bare Win32 programming terms, I'm asking about parameter values for dwStyle as when calling CreateWindow (WS_... constants), or CreateWindowEx (WS_EX_... constants). For delphi users, these values would be set in the CreateParams method, which you would override, and then set Params.Style := WS_xxx; For MFC/C++ users and C users, something in your framework would eventually be calling CreateWindow, with this dwStyle value.

In delphi terms, setting your form.BorderStyle=bsNone, results in dwStyle=WS_POPUP. However I want a borderless window without using dwStyle=WS_POPUP.

Note: All the answers below are good, but using each in production scenarios is problematic, and my attempts to do so, have resulted in encountering many glitches, which for a professional quality application, I still find I can not work around. Davids answer is a great pure Win32 API answer though, and fits the bill. It seems that an industrial strength solution should combine multiple qualities, including all those I have in my question above. In short, borderless forms using BorderStyle=bsNone (dwStyle=WS_POPUP) block all Windows functionality that usually applies to main windows of applications, and all the solutions below solve part of it.

Based on David's suggestions, I wrote the following, which doesn't work: I want a window without a border, that behaves in all ways, like a windows application window, to the system, that is, it can be minimized/restored by clicking on the window in the taskbar, and will be minimized by WindowsKey+M. I am beginning to think that the only way to do this is to add non-client paint code and to resize the top nonclient area bounds to zero. This is of course not a trivial idea.

It turns out that I made a simple mistake in my coding (hence the two paragraphs above) and in fact the code below does now work as I desire. This one is in pascal, but it should be easy to convert it to C++ or anything else.

program NoBorderProject;

uses
  Windows, Messages;
  {the Messages unit contains the windows
  Message constants like WM_COMMAND}

{$R *.RES}

var
  wClass: TWndClass;
  Msg: TMsg;
  win:HWND;
function WindowProc(hWnd,Msg,wParam,lParam:Integer):Integer; stdcall;
begin
 if Msg = WM_DESTROY then PostQuitMessage(0);
 Result := DefWindowProc(hWnd,Msg,wParam,lParam);
end;

begin
 wClass.lpszClassName:= 'CN';
 wClass.lpfnWndProc :=  @WindowProc;
 wClass.hInstance := hInstance;
 wClass.hbrBackground:= 1;
 RegisterClass(wClass);
 win := CreateWindow(wClass.lpszClassName,'Title Bar',
              WS_POPUP,//WS_OVERLAPPEDWINDOW or WS_VISIBLE,
              10,10,340,220,0,0,hInstance,nil);
 SetWindowLong(win, GWL_STYLE, WS_POPUP or WS_MINIMIZEBOX);
 SetWindowLong(win, GWL_EXSTYLE, 0 );
 ShowWindow(win,SW_SHOW);
 while GetMessage(Msg,0,0,0) do
   DispatchMessage(Msg);
end. 
like image 685
Warren P Avatar asked Feb 04 '11 19:02

Warren P


1 Answers

The following gets the job done:

hWnd = CreateWindow(...);
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP | WS_MINIMIZEBOX);
SetWindowLong(hWnd, GWL_EXSTYLE, 0);
ShowWindow(hWnd, ...);

You were probably missing WS_MINIMIZEBOX.

like image 111
David Heffernan Avatar answered Sep 20 '22 17:09

David Heffernan