Jump to content

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

Taskbar-like GUI style where nothing can occupy its space?


  • Please log in to reply
18 replies to this topic
Jaysun
  • Members
  • 20 posts
  • Last active: Sep 25 2006 12:42 AM
  • Joined: 01 Nov 2004
I have created a taskbar replacment for our public access computers (Windows XP SP2) using AutoHotkey. My taskbar sits on the bottom of the screen just like the Windows one. My current problem is that when application windows are maximized their bottom gets covered up by my taskbar. How can I make it so that maximized windows only use the area above my custom taskbar?

BTW, I have tried using Hawkeye's ShellInit (http://www.autohotke...opic.php?t=1901), but I have found that it requires explorer.exe to be running in order to work. I do not run explorer.exe on our public compters for a variety of security reasons so ShellInit isn't my solution.

Thanks much!

Jason Weinstein
Eugene Public Library
Eugene, OR

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005
Try the following:

note: tested with XP SP2, but should work with 95 and later

w := A_ScreenWidth
h := 100

x := 0
y := A_ScreenHeight-h

Gui, +AlwaysOnTop -Caption
Gui, Show, x%x% y%y% w%w% h%h%

VarSetCapacity( old_area, 16 )

; SPI_GETWORKAREA
success := DllCall( "SystemParametersInfo", "uint", 0x30, "uint", 0, "uint", &old_area, "uint", 0 )

VarSetCapacity( area, 16, 0 )

EncodeInteger( A_ScreenWidth, 4, &area, 8 )
EncodeInteger( A_ScreenHeight-h, 4, &area, 12 )

; SPI_SETWORKAREA
success := DllCall( "SystemParametersInfo", "uint", 0x2F, "uint", 0, "uint", &area, "uint", 0 )
if ( ErrorLevel or ! success )
{
	MsgBox, [1] failed: EL = %ErrorLevel%
	ExitApp
}

MsgBox, pausing ...

; SPI_SETWORKAREA
success := DllCall( "SystemParametersInfo", "uint", 0x2F, "uint", 0, "uint", &old_area, "uint", 0 )
if ( ErrorLevel or ! success )
{
	MsgBox, [2] failed: EL = %ErrorLevel%
	ExitApp
}
ExitApp

EncodeInteger( p_value, p_size, p_address, p_offset )
{
	loop, %p_size%
		DllCall( "RtlFillMemory"
			, "uint", p_address+p_offset+A_Index-1
			, "uint", 1
			, "uchar", ( p_value >> ( 8*( A_Index-1 ) ) ) & 0xFF )
}


Jaysun
  • Members
  • 20 posts
  • Last active: Sep 25 2006 12:42 AM
  • Joined: 01 Nov 2004
Very cool! Thanks!

So far, from what I can tell it works perfectly. Now, for my own benifit, I'm trying to figure out exactly what it is doing.

I understand that the dllCall to SystemParametersInfo with the action SPI_SETWORKAREA is creating the margin based on &area. But I'm not yet sure what EncodeInteger is doing to create &area.

Once I'm done tweaking my custom taskbar I'll be sure to post it.

Once again, Thanks!

Jason

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005

Very cool! Thanks!


Sure. You're welcome.

I understand that the dllCall to SystemParametersInfo with the action SPI_SETWORKAREA is creating the margin based on &area.


Self-documenting code... you have to love it.

But I'm not yet sure what EncodeInteger is doing to create &area.


Area is a structure composed of 4 integers. EncodeInteger translates from the textual integer representation used natively by AHk to binary encoded integers which are used natively by the system.

Once I'm done tweaking my custom taskbar I'll be sure to post it.


That's great. I am sure everyone will appreciate your contribution.

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Shimanov, I searched MSDN for documentation on SystemParametersInfo and found this list. There are many parameters, I'm trying to work out how you specified SPI_SETWORKAREA in the following:
success := DllCall( "SystemParametersInfo", "uint", 0x2F, "uint", 0, "uint", &old_area, "uint", 0 )

"Anything worth doing is worth doing slowly." - Mae West
Posted Image

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005

There are many parameters, I'm trying to work out how you specified SPI_SETWORKAREA in the following:

success := DllCall( "SystemParametersInfo", "uint", 0x2F, "uint", 0, "uint", &old_area, "uint", 0 )


I am not sure what you mean by "specify". Does your question refer to determination of the value assigned to SPI_SETWORKAREA (0x2F)?

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Yes, I cannot work out how you determined 0x2F for SPI_SETWORKAREA and 0x30 for SPI_GETWORKAREA. I looked up SystemParametersInfo in API-Guide, and the parameters are listed in similar fashion as on the link to MSDN in my previous post.
"Anything worth doing is worth doing slowly." - Mae West
Posted Image

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005
Check my other post.

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
Thanks! :)
"Anything worth doing is worth doing slowly." - Mae West
Posted Image

not-logged-in-daonlyfreez
  • Guests
  • Last active:
  • Joined: --
Or you can Google it. Works most of the time too :wink:

Serenity
  • Members
  • 1271 posts
  • Last active:
  • Joined: 07 Nov 2004
I have the Platform SDK installed now. It's nice to have all the codes in one place.
"Anything worth doing is worth doing slowly." - Mae West
Posted Image

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I tried the following script, simplified from what Shimanov posted.
VarSetCapacity(area, 16, 0 )
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",176)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth-30)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",A_ScreenHeight)
DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",0) ; SPI_SETWORKAREA
It reserves space for my taskbar on the left, and ObjectDock on the right side of the screen. If I maximize a window, it leaves those areas uncovered.

However, when I try to maximize Pinball (just for test), it flickers for several seconds, and then gets back to the normal (small) windowed size. All my other windows shrink to the size of Pinball, the desktop icons are rearranged. Has anyone seen this behavior? It could be ObjectDock, but it could be also SPI_SETWORKAREA.

l4zphi5h3n7
  • Members
  • 88 posts
  • Last active: Jan 25 2011 07:10 PM
  • Joined: 27 Dec 2006
I tested Laszlo Code here and then I couldn't undo the changes it made!!
I was freaking out. If this happens to you dont sweat it. Right click on your taskbar and unlock, then move to another side of screen and move back. It undoes it.

l4zphi5h3n7
  • Members
  • 88 posts
  • Last active: Jan 25 2011 07:10 PM
  • Joined: 27 Dec 2006
[EDIT]
In your code:

VarSetCapacity(area, 16, 0 )
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",176)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth-30)
DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",A_ScreenHeight)
DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",0) ; SPI_SETWORKAREA

Could you give us some ";" Annotation as to what controls [UP All I need is some help on what controls the top area] left/right/up/down. I have been playing with it for a long time trying to get the following to work: The goal is to check the working area against the monitor area to see if the working area has already been resized. If it has then do nothing. If it hasn't then resize based on where the Windows taskbar is. Read:
WorkLogger:
SysGet, MAr, Monitor, 1
SysGet, MWrk, MonitorWorkArea, 1 ;
;This sections finds where Windows tray is based on size Is this possible with DLL call?
BottomTray := MArBottom - MWrkBottom
RightTray := MArRight - MWrkRight
LeftTray := MArLeft + MWrkLeft
TopTray := MArTop + MWrkTop
GooeyHeight = 60 ; Good height for 4 rows gui
Xpos =
TtlWidth := MWrkRight-MWrkLeft
EditWidth := ttlwidth - 275 ;sets editbox width & leaves room for Some Button and some future functions
TraySize := Toptray + BottomTray + RightTray + LeftTray 
AdjSize := Traysize + GooeyHeight
; Laszlo I'm sure you sould help clean up following section
;This section Assigns top/bottom/left/right to variable for Windows taskbar
IfLess, traysize, 105 ; if already resized do nothing
{
  IfGreater, BottomTray, 0
 {
    TrayLocation = Bottom
    GooeyNewPos := 920
    VarSetCapacity(area, 16, 0 )
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",0) ;Controls Left Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth) ;Controls Right Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",GooeyNewpos) ;Controls Bottom
      DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",0) ; SPI_SETWORKAREA
 }
  IfGreater, RightTray, 0
  {
  TrayLocation = Right
  GooeyNewPos := 948
  VarSetCapacity(area, 16, 0 )
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",0) ;Controls Left Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth-TraySize) ;Controls Right Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",GooeyNewPos-2) ;Controls Bottom
      DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",0) ; SPI_SETWORKAREA

  }
   IfGreater, TopTray, 0
   {
   TrayLocation = Top
   GooeyNewPos := 28
   VarSetCapacity(area, 16, 0 )
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",0) ;Controls Left Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth) ;Controls Right Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",0)  ;Controls Bottom
      DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",GooeyNewPos) ; SPI_SETWORKAREA
   }
    IfGreater, LeftTray, 0
    {
    TrayLocation = Left
      GooeyNewPos := 948
      Xpos := MWrkLeft
            VarSetCapacity(area, 16, 0 )
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 0, "uint",4, "uint",TraySize) ;Controls Left Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 8, "uint",4, "uint",A_ScreenWidth) ;Controls Right Side
      DllCall("ntoskrnl.exe\RtlFillMemoryUlong" ,"uint",&area + 12,"uint",4, "uint",GooeyNewPos-2) ;Controls Bottom
      DllCall("SystemParametersInfo", "uint",0x2F, "uint",0, "uint",&area, "uint",0) ; SPI_SETWORKAREA
    }

Send #d ; to redraw all windows on re-arrange
Sleep 1000
Send #d
}

Gui, 96:+AlwaysOnTop -Caption +Border    ;Gui Options
gui, 96:font,s10,Courier New
Gui, 96:add, edit,-WantReturn vWorkAppend h%GooeyHEight% w%EditWidth%,%UndoAppend%
Gui, 96:Font, s8, MS Sans Serif
Gui, 96:add, button,ym Default,&Send
Gui, 96:add, button,, &Undo
Gui, 96:add, button, ym, %A_SPace%Lo&G%A_SPace%
Gui, 96:add, button,disabled, &Find
Gui, 96:add, button,disabled ym, T&mSh
Gui, 96:add, button,disabled, `$a&Le
Gui, 96:add, button,disabled ym, &Timer
Gui, 96:add, button,disabled, &Alarm
Gui, 96:add, button, ym,&Hide
Gui, 96:add, button,disabled, Lnchr
Gui, 96:Show, w%MwrkRight% x%MWrkLeft% y%GooeyNewPos%  ; Would like it to adjust its size one line at a time for each carriage return
Any/All Help appreciated

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The original script works as described: it sets the work area of the default monitor by filling up a structure of 4 words, with the positions of the edges, and by calling the system function SystemParametersInfo with the first parameter 0x2F = SPI_SETWORKAREA, and with the address of the structure.

It does not resize existing windows, though. If you maximize a window, it will occupy the new working area, but it gets restored to its original position. If you manually resize a normal window, it will be restricted to the new work area, but existing windows still occupy their original space.
GetWorkArea(left, top, right, bottom)
MsgBox [%left%], [%top%], [%right%], [%bottom%]

SetWorkArea(left,top,right-100,bottom)
GetWorkArea(left, top, right, bottom)
WinMaximize AutoHotkey Help
MsgBox [%left%], [%top%], [%right%], [%bottom%]
WinRestore AutoHotkey Help

SetWorkArea(left,top,A_ScreenWidth,bottom)
GetWorkArea(left, top, right, bottom)
MsgBox [%left%], [%top%], [%right%], [%bottom%]

GetWorkArea(ByRef _left, ByRef _top, ByRef _right, ByRef _bottom) {
   SysGet _, MonitorWorkArea
} ; left, top != 0; right != A_ScreenWidth; bottom != A_ScreenHeight ==> taskbar or reserved area

SetWorkArea(left,top,right,bottom) {
   VarSetCapacity(area, 16)
   DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&area + 0, UInt,4, UInt,left)
   DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&area + 4, UInt,4, UInt,top)
   DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&area + 8, UInt,4, UInt,right)
   DllCall("ntoskrnl.exe\RtlFillMemoryUlong", UInt,&area + 12,UInt,4, UInt,bottom)
   DllCall("SystemParametersInfo", UInt,0x2F, UInt,0, UInt,&area, UInt,0) ; SPI_SETWORKAREA
} ; set the current work area of the main monitor; existing windows are not resized!
SysGet ..., MonitorWorkArea gets the current edges. It can be encapsulated in a function, like GetWorkArea above. Its 4 parameter variables are updated with the current edges, and just compare them to 0 or to the screen height and width to find out if the work area has been modified.

The following command finds out the position of the Taskbar: X, Y, W, H for its position of the left, top corner, its Width and Height.
WinGetPos X, Y, W, H, ahk_class Shell_TrayWnd
MsgBox [%X%], [%Y%], [%W%], [%H%]