6 ms·
Changing the primary display using the Win32 API
- hdjjhhvvhga 4y agoRespect to all those folks who seem to comfortably write Win32 code in Rust. I'm so used to the original C/C++ syntax I need to constantly translate between these in my brain, it hurts.
- moron4hire 4y agoThe documentation--the very links that OP provided--does say all of this. Look in the "Remarks" section of EnumDisplayDevices and ChangeDisplaySettings.
- wongarsu 4y agoI always found the msdn documentation quite good, in the sense that almost every aspect of each API is described. However you have to read it thoroughly, a quick skim often leaves you doing things subtly wrong. I think that's where most people fail. The API is often complex because of how old some parts are and how often things got extended in backwards-compatible ways
- esprehn 4y agoYup, even with a code sample that addresses this situation: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changedisplaysettingsexa#remarks https://docs.microsoft.com/en-us/windows/win32/api/winuser/n... So the whole article is sort of "I reverse engineered software for fun instead of reading the docs" It's a fun read about the quirks of the Windows API though.
- the_only_law 4y agoI don't blame them tbh, Microsoft seems to treat documentation that's not .NET as second class. The Win32 documentation admittedly can be pretty good, when you can easily find what you're looking for. There's ben multiple times where I've gone looking for documentation for a still supported API only to be told "oh yeah the best option is to check out this old ass sample code from 2008"
- legalcorrection 4y ago2008 would be too long ago for web stuff, but in Windows land, that’s plenty recent. Win32 APIs are forever.
- the_only_law 4y agoA single code sample, that's probably poorly commented in my experience is hardly what I'd consider good documentation. OTOH it's pretty easy to get help. People I know very skilled with the Windows API seems to be documentation themselves. I have seen RE guys casually bring up undocumented behavior of certain APIs off the top of their head.
- michidk 4y agoOh. This is embarrassing! I totally disregarded the remarks section when reading through all the different system calls. This example is actually quite helpful and would have saved me from hours of research. Lesson learned, i guess.
- ogurechny 4y agoYep, doesn't seem to be an arcane knowledge: https://archive.org/details/windowsgraphicsp00juli/page/658/mode/2up https://archive.org/details/windowsgraphicsp00juli/page/658/... It would be more interesting to find out why the order of monitors changes “randomly” (computers can't really do anything randomly unless asked specifically). It could be something simple, like background driver updates that reset options they shouldn't reset, or the powered down state of monitors on boot, or video card enumerating connected devices differently, etc.
- alin23 4y agoMost users of my Lunar app (https://lunar.fyi https://lunar.fyi) that were coming from Windows, have been praising the Windows multi monitor experience while the Mac felt limited in the handling of external monitors. I admit that finding a way to change monitor brightness [1] or turn off individual displays [2] wasn’t as straightforward and needed a lot of reverse engineering. But macOS has a much nicer API [3] for configuring screen position, resolution, mirroring etc. It’s not without its quirks however, I ran into a lot of bugs while developing the Blackout feature when having to create multiple mirror sets with multiple displays in each one. I finally had to reverse engineer the MonitorPanel.framework that’s used by System Preferences to get that functionality. [4] From my understanding, Windows has a native way of disabling a display in software so this wouldn’t even be needed there. [1] https://alinpanaitiu.com/blog/journey-to-ddc-on-m1-macs/ https://alinpanaitiu.com/blog/journey-to-ddc-on-m1-macs/ [2] https://lunar.fyi/#blackout https://lunar.fyi/#blackout [3] https://developer.apple.com/documentation/coregraphics/quartz_display_services https://developer.apple.com/documentation/coregraphics/quart... [4] https://github.com/alin23/monitorpanel https://github.com/alin23/monitorpanel
- Scene_Cast2 4y agoYour comment makes it sound like Lunar app has Windows builds, but the website implies that it's Mac only. Could you clarify? I'm currently running Windows, and I'd love to check out Lunar if it's available.
- alin23 4y agoIt is macOS only, sorry if I wasn’t clear on that. I was talking about the “Lunar users that were coming from Windows” so I thought it implies that Lunar isn’t for Windows. You can get TwinkleTray for Windows that can do most of what Lunar does: https://twinkletray.com/ https://twinkletray.com/
- phnx88 4y ago[dead]
- unlog 4y agoI have been thinking to automate "when an app enters fullscreen, disable all the non-primary screens". mostly for gaming. Thanks for the MultiMonitorTool hint as that will probably help in combination with AHK! I'm trying to avoid composite. On a somehow related note, I can't recommend MouseUnSnag enough for multimonitors setups https://github.com/MouseUnSnag/MouseUnSnag https://github.com/MouseUnSnag/MouseUnSnag
- michidk 4y agoThat's an interesting idea! I guess the problem would be that all other windows and icons would then be moved to the window that is running the fullscreen app. MouseUnSnag solves a problem that annoyed me for a while now, but I wasn't aware that there is already a solution. Thanks!
- CrendKing 4y agoI thought ChangeDisplaySettingsEx and EnumDisplaySettings are superseded by SetDisplayConfig and QueryDisplayConfig, respectively? https://github.com/MicrosoftDocs/windows-driver-docs/blob/staging/windows-driver-docs-pr/display/scaling-the-desktop-image.md https://github.com/MicrosoftDocs/windows-driver-docs/blob/st... calls ChangeDisplaySettingsEx "legacy API". From my experience, changing topology using SetDisplayConfig is straightforward.
- michidk 4y agoBut I don't see a way to set the primary display using those calls, or am I missing something?
- CrendKing 4y agoWhichever monitor's position is set to (0, 0) is the primary monitor. The following code assumes you have two monitors, and swaps the primary. Of course, to be more robust, you should not hard code the indices but do checking on the info types. let mut num_paths = MaybeUninit::uninit(); let mut num_mode_infos = MaybeUninit::uninit(); GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, num_paths.as_mut_ptr(), num_mode_infos.as_mut_ptr()); let mut paths = vec![Default::default(); num_paths.assume_init() as _]; let mut mode_infos = vec![Default::default(); num_mode_infos.assume_init() as _]; QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, num_paths.as_mut_ptr(), paths.as_mut_ptr(), num_mode_infos.as_mut_ptr(), mode_infos.as_mut_ptr(), null_mut()); (mode_infos[1].Anonymous.sourceMode.position, mode_infos[3].Anonymous.sourceMode.position) = (mode_infos[3].Anonymous.sourceMode.position, mode_infos[1].Anonymous.sourceMode.position); SetDisplayConfig(&paths, &mode_infos, SDC_APPLY | SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_ALLOW_CHANGES);
- dixie_land 4y agoThe coordinate system reminds me of an interesting trivia I read from The Old New Thing: Windows 9x “parks” minimized windows at (3000, 3000) , a coordinate that is unlikely to be seen, at the time (remember 1024x768 was hi-res?) https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453 https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37...
- steinuil 4y agoI wrote an F# tool specifically for changing the primary display not too long ago. This is the code that calls the Win32 API to query the displays and set the primary one. https://github.com/steinuil/SatouinDp/blob/master/DisplayDevice.fs https://github.com/steinuil/SatouinDp/blob/master/DisplayDev... One thing I never figured out was how to map the displays you get from EnumDisplayDevices to the names you see in the display settings, or how to list them in a consistent order.
- londons_explore 4y agoWhen you have used the display config tool in Windows 9x to XP, you see why this API is like this. The API lets you position each monitor independently on the 'virtual desktop', and sometimes there are constraints which mean certain positions aren't possible - and the API needs to give feedback on if a position, colour depth and resolution is allowed. Then you hit 'apply' and the change takes effect. I don't really see any better way to implement the API without leaking implementation details which might change in future windows versions.
- kulhur 4y agonircmd has this functionality (haven't tried it myself so no guarantees) https://nircmd.nirsoft.net/setprimarydisplay.html https://nircmd.nirsoft.net/setprimarydisplay.html It also has a bunch of other useful features like changing the default audio device (something I use every day) and opening the CD tray ;) Anyway, it's the best tool I've used for scripting stuff on windows. No GUI, just a bunch of useful or less useful command line utilities.