SetLayeredWindowAttributes not working under certain conditions - c++

I'm making this app in Haxe which compiles to C++ code. I'm using the SetLayeredWindowAttributes() function to set the background of the window to be fully transparent. The problem is that this works completely fine only on certain monitors, but not on others.
If I launch the app on my main monitor, which I believe to be 32-bit (if that matters), the background doesn't change at all, or will flicker and then completely disappear until I focus another window.
However, if I connect another monitor and run the app on that one, the background does become transparent, and the transparency persists even if I move it back to my main monitor. Even with the 2nd monitor connected at the same time. If I launch it on the main one, transparency fails.
I have tried changing the color values between 0xFFffffff/0xffffff, etc, but no combination of these work.
This same problem occurs even on a completely different machine with different hardware than mine. My hardware: Lenovo Ideapad L340-15IRH, i5-9300H, Gpu(s) Gtx 1650, Intel HD 630.
Please help me, what am I doing wrong?
Code to enable transparency, using windows.h inside a C++ function:
HWND hWnd = GetActiveWindow();
res = SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 0, LWA_COLORKEY);
Code which creates the transparent background, in main haxe code:
transparentsquare = new FlxSprite(0, 0).makeGraphic(screenW, screenH, FlxColor.WHITE);
add(transparentsquare);
It doesn't matter if I enable transparency before everything has loaded, I can enable it by pressing a key at any time and it still fails if I enable it after the app has fully loaded. Also, obviously graphics are not drawn in the C++ function but in the haxe code, so I can't use any fancy DirectX APIs and what-not.

Related

Use Magnification API to capture sub screen failed on Windows10

Magnification API can work well when used to capture primary screen, but when i use it to capture sub screen,after MagSetWindowSource() called, MagSetImageScalingCallback() not triggerd.
I checked the window position is set correctly, in my computer is {-1080, -250, 0, 1670}, and i showed the window, it placed on the right position.
I use the following code to get sub screenshot, just same with the webrtc code, but MagSetImageScalingCallback() not triggerd.
// Create the host window.
host_window_ = CreateWindowExW(WS_EX_LAYERED, kMagnifierHostClass,
kHostWindowName, 0, 0,
0, 0, 0, nullptr, nullptr, hInstance, nullptr);
// Create the magnifier control.
magnifier_window_ = CreateWindowW(kMagnifierWindowClass,
kMagnifierWindowName,
WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
host_window_, nullptr, hInstance, nullptr);
BOOL result = SetWindowPos(magnifier_window_, NULL, rect.left(), rect.top(),
rect.width(), rect.height(), 0);
// value is -1080, -250, 0, 1670
RECT native_rect = {rect.left(), rect.top(), rect.right(), rect.bottom()};
result = set_window_source_func_(magnifier_window_, native_rect);
The working environment is Windows 10 Professional 64bit, my application is also 64bit, my primary screen is plugged in discrete graphics card, sub screen is plugged in integrated graphics.
In the documentation of the MagSetImageScalingCallback, which can be found here, it specifies a few things to take into account:
"This function requires Windows Display Driver Model (WDDM)-capable video cards." You might want to check if the other screen is running via a different videocard, maybe the driver isn't WDDM capable.
"This function works only when Desktop Window Manager (DWM) is off." I'm not sure how much of this statement is true, but as of Windows 8 DWM can no longer be programmatically disabled. You might come into some border cases, I do not think the documentation of this API is kept up to date with all the quicks it might have.
One very important note, you might want to look for a different solution, as this is specified in the documentation: "The MagSetImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality."
Is there any specific reason why you want to use this Windows API, maybe an alternative is a better choice? I am quite familiar with making screenshots, but I'm more of a C# guy, but some c++ examples that look usable can be found here. The GDI way pretty much describes what I use in Greenshot, and this works without any big issues.
P.S.
If my information doesn't help, you might want to extend your question with more information on your setup, like Windows version, is it 32/64 bit, is your application 32/64 bit, graphics card, screens etc.

OpenGL tearing with fullscreen native resolution

I've got an OpenGL application with win32 api without glut etc...and I run into a problem with screen tearing in fullscreen.
Basicly I have set WS_POPUP as a window style and resolution of my monitor as window size.
I'm running on AMD radeon HD 7770 and I see terrible tearing!
When I put WS_POPUPWINDOW style instead of WS_POPUP, the tearing is gone, however I have unwanted border around my scene.
Another thing I noticed is fact, that the tearing disappears when the resolution is NOT native.
So when I pass my_screen_resolution + 1 as size parameter, the tearing is gone.
RESx = 1920;
RESy = 1080;
hwnd = CreateWindowEx(NULL, NAME, NAME, WS_POPUP, 0, 0, RESx, RESy, NULL, NULL, hInstance, NULL);
SetWindowPos(hwnd, 0, -1, -1, RESx + 1, RESy + 1, 0); // With this function call, the tearing disappears!
What can I do to get rid of the tearing without having to run on not native resolution?
EDIT: (Hint: It's not V-sync)
What can I do to get rid of the tearing without having to run on not native resolution?
EDIT: (Hint: It's not V-sync)
Yes it is V-Sync.
When you make a fullscreen window, it will bypass the DWM compositor.
If the window is not covering the full screen its contents are going through the DWM compositor. The DWM compositor itself makes itself a copy of the window's contents whenever something indicates, that it is done drawing (return from WM_PAINT handler, EndPaint or SwapBuffers called). The composition itself happens V-synced.
Thanks for your advice, but I want to aviod the tearing without vsync. With vsync I have terrible input lag.
Then you're doing something wrong in your input processing. Most likely your event loop only processes one input event at a time then does a redraw. If that's the case and your scene complexity goes up, then you're getting lag, that's proportional to your scene's drawing complexity. You don't want this to happen.
What you should do is accumulate all the input events that piled up between redraws and coalesce them into a single new drawing state. Ideally input events are collected until only just before the scene is set up for drawing to reflect the most recent state. If you want to get fancy you my add a Kalman filter to predict the input state at the moment the frame gets shown to the user and use that for drawing the scene.
To remove OpenGL tearing, you should have "enable" vsync. Follow this link for details: how to enable vertical sync in opengl?

C++ Drawing directly to the screen (like an overlay)

Many laptops nowadays have FN hot keys to change volume, brightness, etc. and usually display a visual cue that is rendered on the screen completely above the operating system. For new Windows 8/8.1 systems this visual even appears outside of the desktop in the metro side. They cannot be drawing inside of a borderless window otherwise it wouldn't show up over the metro interface.
I have tried researching whether DirectX can draw directly to the screen but it doesn't appear it can. I don't even know if I should look into OpenGL... ?
I had some success using GDI; specifically the GetDC function with the parameter NULL to grab the screen device.
#include <Windows.h>
int main() {
const HDC dc = GetDC(NULL);
while (1) {
Rectangle(dc, 100, 100, 500, 500);
}
}
However, this requires re-rendering everything repeatedly because my region of the screen can be overwritten by other windows changing in the background. And even with it re-rendering in a loop, there is massive screen flicker.
How do the OEM manufacturers of these laptops achieve this?
Thanks.
It looks like these are borderless windows.
For example, have a look at the task switcher window:
Related question:
Windows 8 Layered Windows Over Metro Apps
If you want a window on top of Metro, you need it to declare accessibility.

Drawing on the screen

I'm currently developing an application with OpenCV to do visual recognition of elements on the screen.
While a visual representation of the process is not needed, it would be very useful for debugging purposes if I could find a way to draw circles, lines and possibly text directly on the screen, without having an app window.
There are certain applications that, for instance, draw HUDs over the screen. How do they go about doing that?
I need a way for my drawing to always be at the front. In general, all the ways I managed to find involve painting on a window (WinAPI, Direct2D, OpenGL). Is there a workaround to make it appear like it's simply a layover on the desktop (including all open windows)?
for the purpose of debugging, just literally draw on the screen. IIRC GetDC(0) will get you a device context for the screen, but check out that whole family of functions. in Windows 7 it doesn't even foul up other applications' displays, and reportedly it's likewise "safe" on the mac.
for example, this draws an ellipse in the upper left of the screen:
#include <windows.h>
int main()
{
HDC const dc = GetDC( 0 );
Ellipse( dc, 10, 10, 200, 200 );
}
the graphic disappears if it's on top of a window and that window is moved.
You can achieve the device context (DC) of the screen, and draw in that DC as usual. The output will be directed to the screen. To achieve that, call WinApi GetDC("DISPLAY"), if i'm not mistaken.

Drawing in a Win32 Console on C++?

What is the best way to draw things in the Console Window on the Win 32 platform using C++?
I know that you can draw simple art using symbols but is there a way of doing something more complex like circles or even bitmaps?
Yes, it is possible.
Get the HWND of the console window using GetConsoleWindow and then draw in it.
#define _WIN32_WINNT 0x601
#include <windows.h>
#include <stdio.h>
int main() {
// Get window handle to console, and device context
HWND console_handle = GetConsoleWindow();
HDC device_context = GetDC(console_handle);
//Here's a 5 pixels wide RED line [from initial 0,0] to 300,300
HPEN pen = CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
SelectObject(device_context, pen);
LineTo(device_context, 300, 300);
ReleaseDC(console_handle, device_context);
getchar();
return 0;
}
Note: GetConsoleWindow was introduced in Windows 2000. It's available when _WIN32_WINNT is set to 0x500 or greater.
No you can't just do that because Win32 console doesn't support those methods. You can however use GDI to draw on the console window.
This is a great example of drawing a bitmap on a console by creating a child window on it:
http://www.daniweb.com/code/snippet216431.html
And this tells you how to draw lines and circles:
http://www.daniweb.com/code/snippet216430.html
This isn't really drawing in the console though. This is sort of drawing "over" the console but it still does the trick pretty well.
It is possible, albeit totally undocumented, to create a console screen buffer that uses an HBITMAP that is shared between the console window process and the calling process. This is the approach that NTVDM takes to display graphics once a DOS application switches to graphics mode.
See it.
As Nick Brooks has pointed out, you can use GDI calls in console apps, but the graphics cannot appear in the same window as the text console I/O. This may not matter since you can draw text elements in GDI.
A simplified interface to GDI calls in console apps is provided by WinBGIm. It is a clone of Borland's DOS BGI API, but with extensions to handle resizable windows, mouse input, and 24bit colour models. Since it is available as source code, it also serves a good demonstration of using GDI in this way.
It is possible to either have both a console and the GDI window, or you can suppress the console window by specifying that the application is a GUI app (the -mwindows linker option in GNU toolchain) - note that specifying a GUI app really only suppresses the console, it is only really a GUI app if it has a message loop. Having the console is good for debugging, since it is where stdout and stderr are output to by default.
Not without usng ASCII art. Back in the days of DOS it was "fairly" easy to do by redesigning the character bitmaps. It might only be possible in windows by creating your own font, but im really not sure thats possible