I want to access the DisplayInformation class from a background task in my UWP that takes an image and resizes it from its native resolution to the size of the user's screen, so that it can be set as a wallpaper.
However, when I attempt to use DisplayInformation.GetForCurrentView(), an exception is thrown, saying that the method must be called from a thread associated with a CoreWindow. How can I avoid this?
Any solution will work as long as it will give me the complete width and height of the user's screen in raw pixels.
This API requires a CoreWindow because you could have multiple monitors on your system, and it needs to know which one to pick (it picks the one that is currently showing the window). The best solution is to query the properties when your foreground app is running, and then save them for later use. (Of course this won't be perfect if the user has two or more monitors of different sizes and you pick the "wrong" one, or they upgrade the monitor, etc. but it's the best you can do).
Related
Every application in Windows 8 starts from this kind of view
(below is camera application) :
My question is :
Is this possible to change programmatically this view for
progress bar (C# or XAML) or any other animation ?
Or is this view related with time computer need to start application so
we can not use resource of our app yet ?
You cannot change how the launch screen is displayed. You can only change the picture and color.
However, the way to extend the launch screen is to make sure your app's first action is to display another launch screen (typically identical to the first with an added progress bar) while the rest of the app is getting ready. This approach is described in this guide.
Please keep in mind that an extended load screen might not be the best user experience. After all the user is still waiting for the app to launch. I recommend that you optimize launch time to avoid using the extended launch screen if you can. I cover this in more detail in my book (sorry for the shameless plug).
That screen is displayed while the runtime is starting your application. Its an image as defined by your application, so to my knowledge, there is no way to inject logic.
However, you can make your app "start" fast (so that the runtime removes the "loading" image), then put up a splash screen while the rest of your content loads. The NFL for Windows 8 app does a good job of this, as do several other apps.
How does one get the screen resolution of the current monitor? By "current monitor", I mean the one that the application starts on.
The reason I ask this is because I have two monitors, the secondary monitor is 1280x1024 and the primary is 1680x1050. The application, when it starts, stupidly sets its own height and width based on the primary monitor resolution. When the application launches on the secondary monitor, it overflows the resolution, which looks strange.
I know I could change/remove the code that sets the application's height/width, but I am also curious how one determines which monitor the application is showing on.
For what it's worth, I am not a proponent of applications that set their own height/width.
Use Screen.FromControl:
Screen.FromControl(this).Bounds
where this is the Form that you want to retrieve the Screen information for.
I have found the foreground window on my desktop using the GetForegroundWindow() function. I need to keep track of how much time each application spends in the foreground and update it in the database each time in resumes to the foreground.
Is there an API to set the counter or find when the window is not in focus?
There is WH_CBT hook type supported by SetWindowsHookEx, which fires every time user switches to another window or application. How to install Windows hooks from C#.
However, if you don't need perfect accuracy, it's much easier to just call GetForegroundWindow() once per second and check if the numerical value of the returned HWND has changed. For something like an activity tracker app which does not need to notice half-a-second intervals this technique is a better choice.
Tips:
GetForegroundWindow() returns the handle of the window that is currently in focus (which can be desktop or taskbar or floating widget so you may need to filter that), or zero handle if there is no window currently focused.
It is ultra-fast so there is no harm in calling it tens or hundreds times a second.
Window handle values are unique (at least in the current user session), different even when they belong to different applications, and they are assigned in a way that a destroyed handle is almost never immediately reassigned.
If you are concerned about your own application, you may handle Activate/Focus/LostFocus/DeActivate events. If you need to monitor all windows, you need to use Windows Hooks for this. One article here.
Users complain that when they have several minimized windows in MDI container it's impossible to distinguish them unless they resore each. I wonder if it's possible to make minimized window a little bit wider so the text in the caption can contain 6 characters?
Thanks in advance!
No, this is not possible. Windows determines the width of a minimized window using the current system parameters, and there's no way to change this dynamically for a single application without changing the values across the entire system.
Specifically, the default size of all minimized windows is 160x31. In a MDI application, you actually get to see this size because the window is minimized into its MDI host, rather than into the Windows taskbar. Raymond Chen (a developer on the Windows Shell team at Microsoft) published a couple of blog entries a while back that explain why this particular size was chosen, and what it means. The first is available here: Why do minimized windows have an apparent size of 160x31? And the second follow-up entry can be read here: No, really, why is it 160x31? As he explains in that second post:
The width of the miniature title bar is determined by the iWidth member of MINIMIZEDMETRICS structure. You can retrieve and change this structure with the help of the SystemParametersInfo function. (Use the SPI_GETMINIMIZEDMETRICS and SPI_SETMINIMIZEDMETRICS flags, respectively.) Some people will mention the MinWidth registry value, but those people are wrong. Notice, for example, that messing with MinWidth requires a logoff cycle, whereas using SPI_SETMINIMIZEDMETRICS takes effect immediately. That's because SPI_SETMINIMIZEDMETRICS updates the internal state variables, whereas whacking the registry just change a value in a database that nobody pays attention to once you've logged on.
What about the height? That's just the height of a caption bar, which you can adjust from the Appearance tab of the Display control panel. (Programmatically, you can use that helpful SystemParametersInfo function, this time using the iCaptionHeight member of the NONCLIENTMETRICS structure.)
Since I doubt your users really want you messing with their default system parameters by P/Invoking the SystemParametersInfo function, you aren't left with a whole lot of options. My recommendation, especially if they're working with a single window at a time and leaving the others minimized, is to switch to an alternative interface. The intention of MDI was to allow users to tile or cascade multiple windows so that they could see more than one at a time. Since it sounds like that's not the typical use case, you might both be better served by switching the application to use tabs instead. This is often called a tabbed document interface (TDI), a somewhat more modern implementation of the old multiple document interface (MDI). It's become quite popular over the years; check out the Wikipedia article.
[Although this post is 11 years old, i'm trying...:
I'm facing an issue with in-app minimized windows, which are broken on my Windows11 (certainly by a software, but I don't know which one...). Those in-app minimized windows are much more narrower that it should be. Instead of having the minimized title bar containing title and 3 buttons, I can only see the close button. You said here it wasn't possible to change this size for a unique software, but I assume you know(knew) where to change it for the whole system? Here is a capture of the issue in ultraedit 1 and here in 3dsMax for example 2
To those who have the same problem as me, I found the solution:
(win+r) regedit
HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics
add the string value "MinWidth".
Change the string value named "MinWidth". Set its value using the following formula:
-15*width in pixels
For me, acceptable one was -3300
Little drawback: It also changes size of the minimized windows in the taskbar (make them much wider when there is a few of them in taskbar)
I just write my first C# application, which is a scheduler. Once an hour I want to pop-up a dialog and lock the screen for two minutes in order to take a break.
As of now, my application just shows a form on "TopMost" when its time to break and hides it two minutes later.
How can I lock the screen as well? Something similar to the UAC style in Vista.
Eep, misread your question. The UAC dialog of Vista creates a new desktop and shows itself on that. To Create a desktop you can use the CreateDesktop function. You can then use SwitchDesktop to switch to it.
If you truly want to re-create the secure desktop's looks, then you need to take a screenshot first and display that on your form, darkened a little.
Original answer below, which might be of interest too:
Take a look at the LockWorkStation function.
However, you can't programmatically unlock the work station again. That's something the user has to do himself. So you can't easily enfore a break at least two minutes long unless you still resort to your top-level window technique to deny the user his workspace as long as the two minutes are not yet over.
As an alternative to taking a screen grab (which I've also used as an approach in the past under slightly different circumstances) you can also do this by creating a new window (WinForm) that is full screen and on top of all other windows.
If you set the window background colour to solid black then set the opacity to 70-80%, you'll get something that looks like the UAC prompt.
e.g.
formName.WindowState = FormWindowState.Maximized;
formName.FormBorderStyle = FormBorderStyle.None;
formName.Opacity = 0.70;
formName.TopMost = true;
Of course it would be sensible to draw a window on top of this informing the user why the screen has been dimmed, with a counter.
Using something that looks enough like a UAC prompt (which people are accustomed to seeing) to not have people even think twice about it might be enough depending on the use case.
As with the screen grab approach, this on it's own does not prevent a user from bypassing it by using the Windows key, Alt-Tab or Ctrl-Esc to bring up the Start menu, or to switch to other tasks.
Disabling built in key commands requires setting Registry Keys relating to Windows Hotkeys and is a bit more tricky (I think it requires a reboot and can't be toggled on the fly).