Can you create the main window of a Borderless Application on Windows without the WS_POPUP style?

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

  • WindowsKey + M minimizes all windows except the main application window.

  • By clicking once on the taskbar (in win7), and then again, you need to switch the state / visibility of the main application window between normal and minimized state. This does not work for such a window.

In simple Win32 programming terms, I ask about the values โ€‹โ€‹of the dwStyle parameter, as when calling CreateWindow (WS _... constants) or CreateWindowEx (WS_EX _... constants). For delphi users, these values โ€‹โ€‹will be set in the CreateParams method that you would override, and then set Params.Style: = WS_xxx; For MFC / C ++ users and C users, something in your structure will eventually call CreateWindow with this dwStyle value.

In terms of delphi, setting your form .BorderStyle = bsNone, the result is: dwStyle = WS_POPUP. However, I want a borderless window without using dwStyle = WS_POPUP.

Note. All of the answers below are good, but using each of the production scenarios is problematic, and my attempts to do this have led to many crashes, which for a professional-quality application, I still think I canโ€™t work. Davids answer is a great answer to the Win32 API but also suitable for the bill. It seems that an industrial power solution should combine several qualities, including all those that I have in my question above. In short, unlimited forms using BorderStyle = bsNone (dwStyle = WS_POPUP) block all the Windows functions that are usually applied to the main application windows, and all the solutions below solve its part.

Based on Davidโ€™s suggestions, I wrote the following that doesnโ€™t work: I want a window without a frame that behaves in every way, like a Windows application window, to the system, that is, it can be minimized / restored by clicking on the window on the taskbar , and WindowsKey + M will be minimized. I'm starting to think that the only way to do this is to add a non-client paint code and resize the upper borders of the non-client area to zero. This, of course, is not a trivial idea.

It turns out I made a simple mistake in my coding (hence the two paragraphs above), and in fact the code below works now the way I want. This file is in pascal, but it is easy to convert it to C ++ or something 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. 
+8
visual-c ++ winapi delphi
source share
3 answers

The following does the job:

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

You were probably missing WS_MINIMIZEBOX .

+13
source share

A bit icky, but you can set the window area by placing this in the YourForm.OnShow event:

 var r: TRect; begin r := ClientRect; OffsetRect(r, 0, GetSystemMetrics(SM_CYCAPTION)); OffsetRect(r, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME)); SetWindowRgn(Handle, CreateRectRgn( r.Left, r.Top, ClientWidth + r.Left, ClientHeight + r.Top), True); 
+4
source share

You need to override TForm.CreateParams and set or remove any style that interests you

 procedure TYourForm.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); Params.Style := Params.Style and Params.ExStyle := Params.ExStyle or ; end; 
-4
source share

All Articles