Why CreateWindowEx will add WS_CAPTION by default? - c++

I'm trying to create an window by CreateWindowEx, but seams even I give both dwExStyle dwStyle value 0, the window still have WS_CAPTION style.
Code snippet as following:
_hWnd = CreateWindowExW(iExStyle, pszClassName, pszTitle, iStyle | WS_CLIPCHILDREN, dX, dY, dWidth, dHeight,
hWndParent, 0, hInstance, NULL);
ASSERT(GetWindowLong(_hWnd, GWL_STYLE) & WS_CAPTION == 0); //<---- This will failed.

dwStyle = 0x00000000L means WS_OVERLAPPED or WS_TILED, this window has a title bar and a border.
Window Styles

As emax says, WS_OVERLAPPED (0) is the default and results in:
The window is an overlapped window. An overlapped window has a title bar and a border. Same as the WS_TILED style.
If you are creating a child window you must specify WS_CHILD and if you are creating a "popup" window you must use WS_POPUP or WS_POPUPWINDOW.
A tooltip for example would use WS_POPUP and WS_EX_TOOLWINDOW + WS_EX_TOPMOST...

Related

How to set a static window size ImGui?

I am new to ImGui, and trying to set the max and min window size. I am using the example dx10 ImGui code. I understand that this line will set the width and hight of the window at the start to be 600*800:
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Micheal's Application", WS_OVERLAPPEDWINDOW, 100, 100, 600, 800, NULL, NULL, wc.hInstance, NULL);
How do I disable the user's ability to resize this window?
WS_OVERLAPPEDWINDOW is defined as
(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
where
WS_THICKFRAME 0x00040000L The window has a sizing border. Same as the WS_SIZEBOX style.
So, you need to clear WS_THICKFRAME bit in the window style:
WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME

CWnd::CreateEx() fails after replacing WS_CHILD with WS_POPUP

When user click a button, I would like to bring up another window. So in the OnBnClicked..() function, I added following code:
CWnd* window = new CWnd;
BOOL result = window->CreateEx(WS_EX_CLIENTEDGE, _T("STATIC"), _T("Hi"), WS_CHILD | WS_VISIBLE, 0, 0, 20, 20, m_hWnd, (HMENU)1234);
window->ShowWindow(SW_SHOW);
This works, except it created a child window. What I need is a separate window. So I modified the code by changing "WS_CHILD" to "WS_POPUP", and "m_hWnd" to "NULL".
CWnd* window = new CWnd;
BOOL result = window->CreateEx(WS_EX_CLIENTEDGE, _T("STATIC"), _T("Hi"), WS_POPUP | WS_VISIBLE, 0, 0, 20, 20, NULL, (HMENU)1234);
window->ShowWindow(SW_SHOW);
But now, the CreateEx() call returns FALSE. I would appreciate some pointer.
[Edit:]
I updated the code as following. But still seeing the same issue. Also, even when CreateEx() returns FALSE, GetLastError() actually returns 0.
CWnd* window = new CalibrationWindow;
LPCTSTR className = NULL;
if (!className) {
className = AfxRegisterWndClass(
CS_VREDRAW | CS_HREDRAW,
::LoadCursor(NULL, IDC_ARROW),
(HBRUSH) ::GetStockObject(WHITE_BRUSH),
::LoadIcon(NULL, IDI_APPLICATION));
}
BOOL isValid = ::IsWindow(GetSafeHwnd());
BOOL result = window->CreateEx(0, _T(className), _T("Hi"), WS_POPUP | WS_VISIBLE, 0, 0, 20, 20, m_hWnd, (HMENU)1234);
DWORD errorCode;
if (!result) {
errorCode = GetLastError();
}
window->ShowWindow(SW_SHOW);
The nID or nIDorHMenu parameter for CWnd::CreateEx is an 'overloaded' parameter that either specifies a control ID or a menu ID.
For a child window (WS_CHILD window styles) it is the control identifier. You can specify any value as long as it is unique among all child windows with the same parent window.
For a popup window on the other hand (a window that does have WS_CHILD window style) it is the menu identifier. In this case it has to be a valid HMENU. Passing a made up value will cause window creation to fail.
Here's how to create a window out of your CWnd-derived class using a different method:
CWndDerived myWnd;
LPCTSTR className = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,
nullptr,
(HBRUSH) ::GetStockObject(WHITE_BRUSH),
nullptr);
myWnd.CreateEx(
0, // WS_EX_TOPMOST
className,
_T("Title"),
WS_POPUP | WS_BORDER | WS_CAPTION | WS_MAXIMIZEBOX | WS_SYSMENU,
0, 0, 300, 200,
m_hWnd,
nullptr,
nullptr);
This allows you to have your CWndDerived myWnd as a member variable (should you need it) of your other window and retain all the goodies that come with MSVC's MFC class editor.
I hope this helps

Removing a window style after the window's creation

I have created a window with the following code:
hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_WINDOWEDGE, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
The window has the WS_EX_TOPMOST style at the creation time, but I want to remove this style if a button is clicked. I saw reference for SetWindowLong() but I don't know how to use it in this situation.
The documentation for the WS_EX_TOPMOST style states:
To add or remove this style, use the SetWindowPos function.
So, clearly you can't use SetWindowLong to clear this style.
Try:
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

Layered window: Why's the edge rounded automatically?

I am trying to draw a hbitmap with a layeredwindow directly onto the screen. this also works now how it should, yet the left upper corner of the image is always rounded.
I'm creating the window with:
HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT
, szWindowClass, 0,
WS_VISIBLE
, 150,250, width, height, 0, NULL, hInstance, NULL);
Could anyone help me please to solve this problem?
You are using WS_VISIBLE as the window style, which is equivalent to WS_OVERLAPPED | WS_VISIBLE. Overlapped windows have rounded corners at the top.
Use WS_POPUP | WS_VISIBLE instead.

Win32: How to create a bordless popup window

Win32 API provides many styles for window creating and I'm looking for a style that can remove a one-pixel border from the window that I created with this code:
DWORD dwExtStyle = 0;
DWORD dwStyle = WS_POPUPWINDOW;
m_hWnd = CreateWindowEx(
dwExtStyle,
className,
windowName,
dwStyle,
300,
300,
100,
100,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(m_hWnd, SW_SHOW);
and I got the result:
What combination of flags can remove the black border from the window.
Just use WS_POPUP instead of WS_POPUPWINDOW.
The macro WS_POPUPWINDOW is actually a set of flags:
#define WS_POPUPWINDOW (WS_BORDER | WS_POPUP | WS_SYSMENU)
The WS_BORDER flag is the one responsible of your black square.