CreateWindowEx creates old (Windows 7) style border on Windows 10 - c++

Whenever I create a window with CreateWindowEx(...) (exact parameters can be found in the code below), it shows up like an old style window:
Only when I start it on a remote desktop, close the connection and reconnect, it changes to the desired Windows 10 style:
Does it have something to do with the several WM_SETTINGCHANGE messages the application receives when doing this?
Obviously, I want the window to have a modern style upon creation, and not after handling some message.
I've tried different combinations of WS_... style arguments. Oddly enough, the application only reliably shows up with WS_OVERLAPPEDWINDOW | WS_VISIBLE.
I've tried ShowWindow (with various arguments) and UpdateWindow in both orders.
I've also tried messing with the target platform and toolset, but to no avail (using VS2015, v140).
Code snippet:
WNDCLASSEX wc = {sizeof(WNDCLASSEX), NULL, WindowController::globalEventProcessor,
0L, 0L, GetModuleHandle(NULL), NULL,
LoadCursor(NULL, IDC_ARROW), NULL, NULL,
_T("Window"), NULL};
RegisterClassEx(&wc);
HWND handle = CreateWindowEx(
NULL,
wc.lpszClassName,
_T("Test"),
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
parentWindow ? parentWindow->getHandle() : NULL,
NULL,
wc.hInstance,
reinterpret_cast<LPVOID>(this)
);
if (handle != NULL)
{
... // resizing the window's contents
UpdateWindow(handle);
}

Strangely enough, the solution seems to be to remove WS_VISIBLE from the style flags, and show the window manually:
if (handle != NULL)
{
... // resizing the window's contents
ShowWindow(handle, 1); /* Add this */
UpdateWindow(handle);
}
Which I'm 100% sure I've tried already, but suddenly works. Whatever...

Related

Moving fullscreen window from primary to secondary monitor causes visual artifact on primary monitor

I am trying to move a fullscreen window from the primary monitor to the secondary monitor. However, while the window appears as it should on the secondary monitor, it also still appears on the primary monitor. This is just a visual artifact as clicking the 'window' on the primary monitor causes the program to minimize just like clicking outside of a program normally would.
After maximizing the program the function works as intended and is able to move the program between the two monitors problem free.
What is causing this visual artifact and more importantly, how can it be fixed?
This is the code I am using, mostly found through trial and error by looking at what decreases the visual artifacts and what doesn't.
void MoveFullscreenWindowToMonitor(HWND hwnd, HMONITOR fromMonitor, HMONITOR hMonitor) {
MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
if (GetMonitorInfo(hMonitor, &monitorInfo)) {
RECT monitorRect = monitorInfo.rcMonitor;
int width = monitorRect.right - monitorRect.left;
int height = monitorRect.bottom - monitorRect.top;
// Get the current window style
LONG style = GetWindowLong(hwnd, GWL_STYLE);
// Temporarily remove the WS_POPUP style to exit fullscreen mode
SetWindowLong(hwnd, GWL_STYLE, style & ~WS_POPUP);
// Move the window off the screen before moving it to the new monitor
SetWindowPos(hwnd, NULL, -width, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
// Move the window to the new monitor and resize it to fit the monitor
SetWindowPos(hwnd, NULL, monitorRect.left, monitorRect.top, width, height, SWP_FRAMECHANGED);
// Add the WS_POPUP style back to enter fullscreen mode
SetWindowLong(hwnd, GWL_STYLE, style);
// Move the window to the new monitor to fix the visual artifact
SetWindowPos(hwnd, NULL, monitorRect.left, monitorRect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
// Create a window that spans the entire work area of the original monitor
//This part fixes another weird visual artifact on the target monitor
MONITORINFOEX mi;
mi.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(fromMonitor, &mi);
RECT rect = mi.rcWork;
HWND extrahwnd = CreateWindowEx(0, L"STATIC", NULL, WS_VISIBLE | WS_POPUP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL);
// Force a screen refresh on the original monitor
UpdateWindow(extrahwnd);
// Destroy the window
DestroyWindow(extrahwnd);
// Restore the window and move it to the new monitor to fix the visual artifact
ShowWindow(hwnd, SW_RESTORE);
SetWindowPos(hwnd, NULL, monitorRect.left, monitorRect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
// Give the window focus
SetForegroundWindow(hwnd);
// Invalidate the window to force a redraw on the original monitor
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
EDIT: Everything works perfectly fine if I minimize and then maximize the application before running the code.

Child window disappears on scrolling

HWND hwndDlg=GetDesktopWindow();
HWND hImage=CreateWindow(_T("STATIC"), _T(""), SS_CENTERIMAGE | SS_REALSIZEIMAGE | SS_BITMAP | WS_CHILD | WS_VISIBLE,
550, 480, 10, 10, hwndDlg, NULL,
(HINSTANCE)GetWindowLong(hwndDlg, GWLP_HINSTANCE),
NULL);
LPWSTR imgPath = getImagePath();
HBITMAP bitmap = (HBITMAP)LoadImageW(NULL,imgPath, IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
SendMessage(hImage, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)bitmap);
With this piece of code i'm able to create a child window to the current window and make a picture appear on that window. It works as expected. But my problem is when i scroll the child window and the picture disappear. What am I doing wrong? I'm totally new with windows programming. Please help me out.
http://i.stack.imgur.com/VO0uD.png
You may see the screenschot in the above link

Adding notepad as my inner window

I'm new to Windows Programming and am trying to create a window and have Notepad be an inner window of the parent.
Right now I have something like this:
HWND parent = CreateWindowEx(
0,
L"Class name",
L"Some Text",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
Of course I RegisterClass and all that good stuff first. What I would like to do is be able to call something like:
HINSTANCE child = ShellExecute(
parent,
L"open",
L"C:\\Windows\\System32\\notepad.exe",
NULL,
NULL,
5
);
ShowWindow(parent, 5);
but that will open Notepad in a new window and leave the parent as a seperate window.
I'm thinking I may need to add this support in the draw command but at the same time I don't think it would be necessary to try to draw an .exe as an inner window everytime a draw is requested.
If someone could point me in the right direction that would be great!

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);

Presence of image control in VC++2008

Hello Everyone,
I want to know if there is an image control in VC++ like there is one in VB. Actually using the picture box i face the problem of not being able to re size the image at design time for my dialog. But in image control this is possible. I there is no image control is there a way to check the height and width of a dialog from the dialog editor at design time ???
If you're writing an unmanaged C or C++ project it's a little bit more difficult than using the PictureBox control that would be available when designing managed Windows Forms application, but still doable.
If you are using a DialogBox resource for the window (note: I wrote this part using Visual Studio 2015 as a reference, not 2008, but the general process should be the same):
Insert the image as a resource in your project. Let's say we named the resource for the bitmap IDB_BITMAP1 for simplicity.
Create a new Static child window in the dialog box.
Right click on the new Static window and select Properties.
Under the Misc subheading in Properties, change Type to Bitmap.
Under the Misc subheading in Properties, change Image to IDB_BITMAP1.
If you are hand-coding the window (i.e. manually writing calls to CreateWindow and CreateWindowEx to create the window):
Insert the image as a resource in your project. Make sure to add the line #include "resource.h" to your code.
Get a handle to the bitmap using the LoadBitmap function.
Create the static window as a child window of the main window, and specify the SS_BITMAP window style.
Send the STM_SETIMAGE message to the window using the previously identified handle to the bitmap resource.
Example code, assuming your image is IDB_BITMAP1:
#include <Windows.h>
#include <tchar.h>
#include "resource.h"
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
HWND hWnd, hStcImage;
MSG Msg;
HBITMAP hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
// ... register the window class etc
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, _T("ExampleClassName"), _T("Simple Window"), WS_VISIBLE | WS_SYSMENU, 100, 100, 350, 370, NULL, NULL, hInstance, NULL);
hStcImage = CreateWindow(_T("Static"), NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 10, 10, 0, 0, hWnd, NULL, hInstance, NULL);
SendMessage(hStcImage, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}