ID:909579
 
Get Screen Resolution

This function is for anyone wanting to get the resolution of their player's screen with one simple function. It will only work for people who use an interface file (.DMF). Also it should be noted that this will work safely with any window at all in your interface file.

How It Works

This function works by preparing a window to be rapidly expanded. When it reaches the limit of the player's screen it will stop and record how far it got in two player variables (mob/var).

Namely : currentResX & currentResY

After the process is done it will return the window back to the way it was. Now, you can use any window you like. If you choose to use any non-transparent windows then please not that there will be a 'visual flash'. You can personally stop this from happening by adding a transparent window to your interface file and calling the function on that window. For example getResolution("transparent").

To make a transparent window for this purpose, set the window's background color to something unique such as bright cyan. Then set the transparent color property of that window to the same color. It will become invisible and you're done. Now just switch your call to that window and you won't experience a flash.

Example

mob
Login()
getResolution()
src << "Player's Resolution : [currentResX] , [currentResY]."

// Prints "1366 , 768" for me.


The Code

Simply copy paste this code into your project, it won't clash with anything you have. Now you can use it like in the example above.

Also, please note that the player's resolution variables will only update when this function is called.

mob

var
currentResX = 0
currentResY = 0

proc

getResolution(window) // Can use any window.

if(!window) return

var
winResX = getWinX(window)
winResY = getWinX(window)

winMenu = winget(src,window,"menu")
winTitle = winget(src,window,"titlebar")
winStatus = winget(src,window,"statusbar")
winResize = winget(src,window,"can-resize")

winset(src,window,"menu=false")
winset(src,window,"titlebar=false")
winset(src,window,"statusbar=false")
winset(src,window,"can-resize=false")
winset(src,window,"size = 2000x2000")

currentResX = getWinX(window)
currentResY = getWinY(window)

winset(src,window,"menu=[winMenu]")
winset(src,window,"titlebar=[winTitle]")
winset(src,window,"statusbar=[winStatus]")
winset(src,window,"can-resize=[winResize]")
winset(src,window,"size = [winResX]x[winResY]")

return

getWinX(window)

var/res = getWinRes(window)
if(res)
return res[1]
else return


getWinY(window)

var/res = getWinRes(window)
if(res)
return res[2]
else return


getWinRes(window)

if(!window) return
var/size = winget(src,"[window]","size")
if(size) return text2List(size,"x")
else return


text2List(text, separator) // Written By Deadron | Modified By Red Hall Dev

if(!text || !separator) return

var/textLength = lentext(text)
var/separatorLength = lentext(separator)
var/list/numList = new /list()
var/searchPosition = 1
var/findPosition = 1
var/buggyText
var/loopForever = 1

while(loopForever)
findPosition = findtextEx(text, separator, searchPosition, 0)
buggyText = text2num(copytext(text, searchPosition, findPosition)) // Everything from searchPosition to findPosition goes into a list element.
numList += buggyText // Working around weird problem where "text" != "text" after this copytext().
searchPosition = findPosition + separatorLength // Skip over separator.
if (findPosition == 0) // Didn't find anything at end of string so stop here.
return numList
else
if (searchPosition > textLength) // Found separator at very end of string.
numList += "" // So add empty element.
return numList
Way too many widgets and winsets. consolidate them to get better results.
there is also no reason for text2list, when there is only two values. it is probably easier, and more efficient to just parse it yourself.
In response to Super Saiyan X
Oh yeah, text2List() isn't the best way to do so I'm told. I think you'll find that all of the winsets and wingets are needed though. I mean sure thing you can edit your transparent window and get rid of a lot of them but my system is designed so that any window anywhere can be used to get the user's resolution. If people want to edit what I've done, it's all there.

I'll try work out a copytext() method but after that it should be the best correct method for using DM only. Some people have said to make a javascript call which is cool, I just wanted pure DM for this.
He means that you can combine all of those winset()/winget() calls into a single winset()/winget(). The method is described in the Skin Reference (See "Using winset()" and "Special winget() calls").

Also, it would be preferable to use is-visible instead of transparency, as transparency forces software rendering mode (which can be substantially slower than hardware mode, as well as some other issues).
Your code does not appear to work properly. It does not return the correct resolution. In my case, it returns 1440x860. My resolution is 1440x900. Your example doesn't work either unless I create an interface and pass along the main window as an argument. Perhaps you are not taking into consideration that a maximized window is not going to expand to the entire screen's resolution; it's going to maximize to the area above the Windows' toolbar.

If that's what you really wanted, you can obtain that information much easier and faster without requiring an interface file be defined:

client
var
resolution = ""
resolution_width = 0
resolution_height = 0

proc
getResolution()
winclone(src, "window", "resolution")
winset(src, "button", "parent=resolution;type=button;pos=0,0;size=640x480;anchor1=0,0;anchor2=100,100")
// An anchored control must be created and placed on the
// invisible window. Getting window.size after maximizing it
// will not actually return the size of the maximized window,
// but rather the size before the window was maximized.
// Therefore, we grab the size of this button control instead
// after it has expanded to the size of the invisible window
// when is-maximized is set to true.
winset(src, "resolution", "titlebar=false;statusbar=false;is-maximized=true")
resolution = winget(src, "resolution.button", "size")

mob
Login()
client.getResolution()
..()

world << client.resolution



Alternatively, you can use JavaScript to get the *exact* resolution.

Example I threw together:
client
var
resolution = ""
resolution_width = 0
resolution_height = 0

Topic(href, href_list[])
if(href_list["action"] == "resolution")
resolution_width = text2num(href_list["width"])
resolution_height = text2num(href_list["height"])
resolution = "[resolution_width]x[resolution_height]"

proc/getResolution()
src << browse("<html><head><script type='text/javascript'>window.location='?action=resolution;width='+screen.width+';height='+screen.height+''</script></head></html>", "window=resolution;border=0;size=0x0;can_close=0;can_resize=0;can_minimize=0;titlebar=0")
while(!resolution) sleep(world.tick_lag)
src << browse(null, "window=resolution")

mob
Login()
client.getResolution()
..()


However, I suppose someone might have JavaScript disabled, this does not consider that and it would cause the getResolution() procedure to never return.
In response to Koil
The DM way you specified is basically what I did in my tutorial. Also using javascript in byond isnt the best like you said since it can be turned off.