I am trying to develop a background utility for Windows with the following features :
store position of open application windows for the current display resolution Rx
scan for any change in display resolution Rx -> Ry (e.g. related to docking/undocking my laptop to/from its docking station)
wait for Windows to finish automatic repositioning of the windows (messy desktop reconfiguration; see below)
restore the previously stored windows position for the display resolution Ry
I have successfully implemented features 1, 2 and 4. For feature 2, I intercept the WM_DISPLAYCHANGE event, telling me that a change in display resolution has occurred.
Immediately after the resolution change occurs, Windows automatically repositions many (if not all) windows to meet the new display constraints. This phase (which I call the messy desktop reconfiguration) lasts several seconds and causes a real mess in the windows layout (which is why I want to develop the said utility).
Now I have the following problem:
I can only apply feature 4 when Windows has finished the messy desktop reconfiguration phase (3). However, I have not found any acceptable way to detect when this phase ends.
I did try to observe the automatic repositioning of windows by intercepting the EVENT_OBJECT_LOCATIONCHANGE event, and then wait for the last one to be issued. It almost works: I am well notified when it happens, however, I'm not satisfied because the time interval between each of these events can last up to 5 seconds (or maybe more), which makes it difficult to identify the last of these events by a classic timeout method. Currently, I have set this timeout to 10 seconds, which is not satisfactory because I would like to be able to detect the end of the messy desktop reconfiguration earlier and, more importantly, there is no guarantee that another of these events will not occur after the timeout.
Does anyone have a solution to properly detect the end of automatic windows repositonning, when changing the display resolution ?
Related
I've have found a problem running unity(ver. 2019.4.34f1 and 2021.2.8f1) on my MacBook m1 chip. Whenever I run Playmode while having Scene and Game tab open at the same time I get only around 30fps which is very strange running on m1 chip. But When I closed the Scene tab and ONLY having the Game tab open, the fps jump to 400fps+.
I have:
installed mono, .Net Arm64
Default Unity Configuration
Is there a way to resolve this issue?
I suspect this has to do with a default setting on a LapTop to save power. Try changing the interaction mode under Edit/Preferences/General.
Interaction Mode Specifies how long the Editor can idle before it
updates. After one frame finishes, the Editor waits up to the
specified amount of time before the next frame begins.
This allows you to throttle Editor performance, and reduce consumption
of CPU resources and power.
For example, if you want to test the Editor’s performance, set this
property to No Throttling. If you want to conserve power (for example,
to prolong battery life on a laptop computer), set this property to
one of the throttled modes.
In throttled modes, the Editor stops idling if you interact with it
(for example, by panning in the Scene view).
Note: In Play mode, Unity ignores any throttling that you apply using
this preference. The editor updates as fast as possible unless you
enable the VSync option in the Game view, or set
Application.targetFrameRate to a value other than –1.
Unity Docs
Unlike other mouse events, double-click events are optional in Windows. A window does not receive double-click events unless developer specifically
opts in to receive them (by registering window class with CS_DBLCLKS style).
I'm wondering why that is? Is there a performance or compatibility penalty when enabling double-click detection, and that's why this setting is optional? Or is it just a historic remnant that is not relevant anymore?
Basically, my question is, is there any disadvantage to enabling this style for all windows in an application?
#Jabberwocky points out that the link provided in the question gives the reason. To receive DBLCLK messages, register the window class to receive them.
Taking a deliberate decision to register or not for DBLCLK messages is useful depending on the target application.
For mouse-operated applications, some sort of double-click functionality is common. Register for and process these messages.
However, touchscreen applications are operated by a stubby human finger and give inconsistent results depending on who operates the touchscreen. In addition, several Windows registry settings affect mouse sensitivity in HKEY_CURRENT_USER\Control Panel\Mouse:
DoubleClickHeight (default = 4 on Windows 10)
DoubleClickWidth (default = 4)
DoubleClickSpeed (default = 500)
Width and Height refer to how far apart (in pixels) clicks are allowed to be to be considered "double-clicks". Too far away, and two rapid clicks are not a double-click. If double-click functionality is required on a touchscreen, Width and Height would be increased.
Speed refers to the time (in ms) between clicks to be considered a double-click, provided both clicks are within the area defined by Width and Height.
Touchscreen applications are usually dedicated to a single application (like an embedded point-of-sale kiosk). They will generally give unreliable double-click functionality and should normally avoid trying to. The embedded Windows system might be configured (see the registry settings above) to allow some use of double-clicks outside of the main application. But the application itself would not register (or use) double-clicks at all.
I am using BitBlt heavily in my project. I create a number of threads and in each thread I capture the screen by BitBlt. It works great and as expected for now except the following problem.
The problem happens when the user clicks on a running program or for example already opened explorer on the taskbar. You know when you click on the running program on the taskbar, it either minimizes or appears on the screen. The issue that I am talking about happens just in this transition. At that moment, something like an interrupt, all threads stop capturing the screen for a fraction of a second and then they continue capturing. The same thing happen when you move down or up the thing on the volume control window. Could you please shed some light why this is happening and how I can prevent this happening?
Thanks.
Jay
It could be a scheduling issue. When you activate an app, it gets a small, momentary boost in its priority (so that it can seem responsive in the UI). This boost might last about as long as the animation and momentarily pre-empt your screen capture threads.
It's also possible that the desktop manager is serializing stuff, and your bitblts are simply stalled until the animation is over. Even if you've turned Aero off, I believe the desktop window manager may still be in compositing mode, which has the effect Hans Passant was describing in the comments.
If you're trying to make a video from the screen, I think it's going to be impossible to rely on GDI. I strongly suggest reading about the Desktop Window Manager. For example, this caveat directly applies to what you're trying to do:
Avoid reading from or writing to a display DC. Although supported by DWM, we do not recommend it because of decreased performance.
When you use GDI to try to read the screen, DWM has to stop what it's doing, possibly render a fresh copy of the desktop to video memory, and to copy data from video memory back to system memory. It's possible that the DWM treats these as lower-priority requests than an animation in progress, so by the time it responds to the BitBlt, the animation is over.
This question suggests that DirectShow with a screen capture filter might be the way to go.
I'm writing WPF application
application targets all sort of windows and low performance computers
so I want to write launcher/splash screen for it which will be displayed before application loads
I'm not sure what language to use or what technology
I want it to be very fast and lightweight
can you suggest anything ?
Displaying a flash screen is as easy as popping up a dialog. If the dialog has the various resources such as bit maps already included then it is quite fast. However one issue that will determine this speed is how much other stuff is being initialized at application startup before the code is hit to display the dialog.
So one option would be to have a very simple application that does nothing more than display the flash screen and then start up the actual application. A simple Windows dialog application would do that. You would need to figure out how to synchronize the actual application finishing its initialization and the launching application stopping if you choose this route. There are several techniques for this and the most likely would be to use an interprocess mutex or perhaps just look for a file to be created.
For a point of sale I work with that is launched as part of turning on the terminal we ran into problems in which the application would start before some required system services such as database manager were up and running.
We have found that some environments require much more time than others so a registry variable makes it easy to tweak the delay in the field.
So as part of the application initialization what we did was that when the application starts up, it displays a dialog with a progress bar. The progress bar does a count up and we have a loop that does a one second sleep then increments the progress bar.
The number of seconds to wait is a registry setting for the application with a default value.
One problem we ran into was that when doing development and testing in a debugger, the default value was way too long for impatient programmers wanting to get started so we have condition compile so that if it is a debug compile, the delay is set to a couple of seconds. Otherwise the default is 10 seconds. However it can be changed with a change in the registry value.
See also this Stackoverflow about a launcher.
If you want something realy fast and lightweight, C would be nice.
If you dont want to learn C, you can also make a console application with .NET and C# it's fast too
Edit for comment: You can use a library like SDL wich is very fast and powerfull, and can draw images from a console application.
Is there some event or notification I can receive or hook each time an external LCD monitor is plugged in or unplugged from a laptop running Windows 7?
The laptop detects this and switches my display to the external screen and back with certain kinds of resizing or repositioning but is this exposed by the operating system so that applications can provide a handler, attach a script, etc?
If not, is there a registry setting or API I could poll from time to time?
(I prefer programming C + Win32 API)
UPDATE
Mike's answer below, WM_DEVICECHANGE led me to RegisterDeviceNotification(), but I'm struggling to implement it so far...
UPDATE 2
This question has been asked with different wording a couple of times, but not fully answered yet in my opinion:
How to detect hot plugging of monitor in a win32 application?
Getting an event on monitor hotplug for windows
According to this article Windows sends the WM_DISPLAYCHANGE message when display resolution changes and also when a display is added or removed.
If you need to react to desktop size changes due to monitor addition or removal, you can do so in the handler of this message. The LPARAM gives you the new resolution of the display on which the window is located. Notice that this resolution will be scaled if you use anything else than 100% for system DPI scaling and your program is not DPI-aware.
Alternatively use the EnumDisplayMonitors function to get the display resolution for each connected monitor and the relative positions of the monitors in the virtual desktop. This functions uses the real device pixel values regardless of DPI scaling.
You can try WM_DEVICECHANGE. If that doesn't do the trick, run your window and attach Spy++ to it which will log all the window messages it receives. Then plug your monitor in and check if you received any messages.
Alternatively you can poll GetSystemMetrics() with SM_CMONITORS.
As said here:
You will see registered messages "UxdDisplayChangeMessage" and "HotplugDetected" (second one only when adding monitor). You can use RegisterWindowMessage to get the identifier for these messages.
There are also other messages you can check, just see the linked answer.