Imho, one should completely avoid fullscreen mode. There is no longer any performance advantage with it, those days are gone.
If you want to cover the entire screen, just create a borderless and captionless window with fullscreen dimensions. This gives you advantages:
- Only one set of code: If going directly fullscreen at program start, one reacts once only on a screen resize, if going to windowed mode, the same code reacts each time a resize event occurs. (And btw, i believe the video memory almost always gets badly beaten from device resizes, so prepare to re-construct various render surfaces).
- Easier development and debugging (multiple windows handy/accessible).
- You can easily extend the application to cover multiple screens, when the user has an "extended desktop" (when one can move mouse cursor from one display to another). Just make the window 6000 px wide for 3 screens and place it at x=-2000 or likewise. Windows provides an API for monitor coordinates & placement.
- Also from the users perspective positive: Allows to place other windows topmost (you must react on lostfocus or hasfocus).
- Be a good to the hardware. Old fullscreen feels destructive...
The easy going way is to not scale. Applications usually try to place their elements starting from upper lefthand corner. Same with a game GUI that may occupy a larger piece of the screen. BUT ofc one can justify isolated screen elements also right & bottom, as long as they aren't too big. Hence a good scaling would be to not alter icon sizes, fonts, picture sizes, etc. but indeed place them nicely according to screen pixels.
Then tell users with too few pixels (and too old hardware) to go grab something newer. Do not support anything too old-fashioned, rather aim at supporting what there will be 3.14 years from now :-).