Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GetDesktopArea function


  • Please log in to reply
5 replies to this topic
PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
[EDIT] As pointed in next message, there is a built-in command for this:
SysGet mon, MonitorWorkArea

Sorry for the noise.
I left the original message below.

---

Althought I found some related topics, I have not seen a function that just return the usable desktop area, ie. the desktop area minus the taskbar and various other possible toolbars.

It can be useful to snap windows to a side of this area, for example (a limitation of Titan's WindowSizing inspired this hack).

So I made this function, designed to be simple to use and fast: I compute the values once, then "cache" them and return them on demand. I had to do that because AutoHotkey cannot return an array or a structure.

/*
// Call this function with "x", "y", "w" or "h" parameter
// to get respectively the top-left coordinates of the desktop area,
// its width or its height.
// The "desktop area" is the screen minus docked toolbars like the taskbar.
*/
GetDesktopArea(p)
{
	static sbSet, sX, sY, sW, sH
	If not sbSet
	{
		; http://support.microsoft.com/support/kb/articles/Q154/8/23.asp
		; RECT structure: left, top, right, bottom
		VarSetCapacity(desktopAreaRect, 16)

		DllCall("SystemParametersInfo"
			, "UInt", 0x30	; uiAction=SPI_GETWORKAREA
			, "UInt", 0	; uiParam
			, "UInt", &desktopAreaRect	; PVOID pvParam
			, "UInt", 0)	; fWinIni
		sX := GetLong(desktopAreaRect, 1)
		sY := GetLong(desktopAreaRect)
		sW := GetLong(desktopAreaRect) - sX
		sH := GetLong(desktopAreaRect) - sY

		sbSet := true
	}
	IfEqual p, x, Return sX
	IfEqual p, y, Return sY
	IfEqual p, w, Return sW
	IfEqual p, h, Return sH
}

GetLong(ByRef struct, pos=0)
{
	local sa
	static sPos

	If (pos != 0)
	{
		; Reset
		sPos = pos
	}
	Else
	{
		; Next
		sPos++
	}
	; Long: 32 bits = 4 bytes
	sa := &struct + (sPos - 1) * 4
	Return *sa + (*(sa+1) << 8) + (*(sa+2) << 16) + (*(sa+3) << 24)
}

Test:
x := GetDesktopArea("x")
y := GetDesktopArea("y")
w := GetDesktopArea("w")
h := GetDesktopArea("h")
MsgBox %x% - %y% - %w% - %h%
Easy enough? :-)
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
What's wrong with
SysGet Mon, MonitorWorkArea

MsgBox %MonLeft% - %MonTop% - %MonRight% - %MonBottom%


PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
That it is hard to find? :lol: :oops: Or too simple to use? ;-)

I stupidly overlooked this one, searching the SPI_GETWORKAREA constant in the page...
It was surprising that Chris didn't provided such a function, it is nice that I was wrong :-) Looks like I reinvented the wheel ;-)

Note: either moderator suppress this obsolete thread, or keep it as the trick of cached variables may inspire other people. But I can reuse it in other scripts.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

toralf
  • Moderators
  • 4035 posts
  • Last active: Aug 20 2014 04:23 PM
  • Joined: 31 Jan 2005
You should edit your first post and mention that there is a simpler solution. So that users find it right away.
Ciao
toralf
 
I use the latest AHK version (1.1.15+)
Please ask questions in forum on ahkscript.org. Why?
For online reference please use these Docs.

JSLover
  • Members
  • 920 posts
  • Last active: Nov 02 2012 09:54 PM
  • Joined: 20 Dec 2004

What's wrong with

...or my SPI_GetWorkArea() / A_ScreenWidthWA() / A_ScreenHeightWA() functions...

msgbox, % "0 - 0 - " A_ScreenWidthWA() " - " A_ScreenHeightWA()
;...is Left/Top ever not 0?...if so...
;msgbox, % SPI_GetWorkArea("Left") " - " SPI_GetWorkArea("Top") " - " A_ScreenWidthWA() " - " A_ScreenHeightWA()

SPI_GetWorkArea(which)
{
	SysGet, WA, MonitorWorkArea
	if which=top
		return WATop
	else if (which="bottom" || which="height")
		return WABottom
	else if which=left
		return WALeft
	else if (which="right" || which="width")
		return WARight
}

A_ScreenWidthWA()
{
	return SPI_GetWorkArea("width")
}

A_ScreenHeightWA()
{
	return SPI_GetWorkArea("height")
}
...why cache?...what if a toolbar is hidden/shown between calls?

I'd like A_ScreenWidthWA / A_ScreenHeightWA as builtin vars (& perhaps A_ScreenLeftWA / A_ScreenTopWA...if they are ever not 0)...& maybe A_ScreenLeftVirt / A_ScreenTopVirt / A_ScreenWidthVirt / A_ScreenHeightVirt (corresponding to the 76 / 77 / 78 / 79 values of the SysGet command).

PhiLho...when you link with p=48008 it's impossible to know which topic it belongs to...plus when you are linking to the 1st post (the topic, not a post in it) you should use...t=8007...or when linking to a post that's not on the 1st page...t=8007&p=48008#48008...it makes it clear which topic it belongs to.
Useful forum links: New content since: Last visitPast weekPast 2 weeks (links will show YOUR posts, not mine)

OMFG, the AutoHotkey forum is IP.board now (yuck!)...I may not be able to continue coming here (& I love AutoHotkey)...I liked phpBB, but not this...ugh...

Note...
I may not reply to any topics (specifically ones I was previously involved in), mostly cuz I can't find the ones I replied to, to continue helping, but also just cuz I can't stand the new forum...phpBB was soo perfect. This is 100% the opposite of "perfect".

I also semi-plan to start my own, phpBB-based AutoHotkey forum (or take over the old one, if he'll let me)
PM me if you're interested in a new phpBB-based forum (I need to know if anyone would use it)
How (or why) did they create the Neil Armstrong memorial site (neilarmstronginfo.com) BEFORE he died?

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005

[What's wrong with]... my SPI_GetWorkArea() / A_ScreenWidthWA() / A_ScreenHeightWA() functions...

Nothing. I searched for SystemParametersInfo, not for MonitorWorkArea...
At least, users reading this topic will have choice now :-)

...why cache?...what if a toolbar is hidden/shown between calls?

Remark is pertinent, but if screen configuration change between calls, you will get incorrect or inconsistent values anyway.
The SysGet command sets 4 variables at once, so at least it is consistent.
These variables can be local.
I see no way to do the same with a function call, keeping result local.
Hence the cache idea: maintain consistency, if not accuracy.
And probably of changes between two calls, which are likely to be successive, is very small.

when you link with p=48008 it's impossible to know which topic it belongs too...plus you are linking to the 1st post...the topic, not a post in it...

It was intentional, I was refering to the program made by Titan, not to a specific comment message. But finally, I understand what you mean by not knowing the topic (see below).

you should use...t=8007...when linking to a topic

Thank you for the tip.
Actually, I don't know how I got this p=48008 (which works), as I usually link to topics by copying the link from the list of topics for a given area.
I will try and be more attentive to this issue.

So, when I put p=xxx, I refer to a given post (the first one in my case), while a t=xxx refers to a given topic (or thread)? Using both designates topic and thread.
Thank you for the information.

I see that p=48008 is a reference to my post about this topic (why did I used it?), although using it alone display the whole topic... OK, I won't repeat the error now.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")