Alaska Software Inc. - Taskbar-size
Username: Password:
AuthorTopic: Taskbar-size
Thomas PoolTaskbar-size
on Fri, 17 Apr 2015 16:09:51 +0200
Hi All,

How can I find out whether the win taskbar is open and position dialogs on
top of it?

Thanks & regards, Thomas
Andreas Gehrs-Pahl
Re: Taskbar-size
on Fri, 17 Apr 2015 18:38:25 -0400
Thomas,

>How can I find out whether the win taskbar is open and position dialogs on
>top of it?

The following function will tell you (indirectly) where the Taskbar(s) 
is/are located and its/their size, by returning the position and size of the 
unoccupied desktop area. This area is used by the OS to position any windows 
(dialogs) on the desktop. To position a dialog on the area that is occupied 
by a taskbar, you would have to tell the OS that the unoccupied desktop area 
is bigger than it actually is. Additionally, the real taskbar(s) will still 
be in the foreground, while your dialog will be hidden behind the taskbar.

You can of course hide the taskbar(s) programmatically, but I know from 
experience that it isn't a good idea to do this in an application, as the 
taskbar will continue to be hidden if your application closes (or crashes) 
before it can restore the taskbar(s). Unless a taskbar is hidden, it will 
always be on top of other dialogs.

Anyway, here is the code (a couple of lines will probably wrap):

#define SPIF_SENDCHANGE      0x0002	 2
#define SPI_SETWORKAREA      0x002F	 47
#define SPI_GETWORKAREA      0x0030	 48
#define TOGGLE_HIDEWINDOW    0x0080	 64
#define TOGGLE_UNHIDEWINDOW  0x0040	 128

Function WindowsWorkArea(aArea)
**************************************************************************
* If "aArea" is supplied, the Windows WorkArea is set to the new area,   
 as if the left-out area is occupied by Taskbar(s) or other things, but 
 no TaskBar(s) is (are) moved. After setting the Windows WorkArea, all  
 Applications recognize this area for functions such as maximizing a    
 Window. The Parameter "aArea" must be NIL or an Array of the following 
 format: "aArea" ==> {"nLeftPos", "nTopPos", "nRightPos", "nBottomPos"} 
 defining the new Workarea in Windows (Pixel) coordinates (Left and Top 
 are both "0", while in Xbase usually Left and Bottom are "0")!!!       *
**************************************************************************
* The current Windows WorkArea (not occupied by Taskbar(s)) is returned  
 as a two-dimensional Array {"aPos", "aSize"}, of the following format: 
 "aPos"  ==> an Array in Xbase coordinates {"nLeft", "nBottom"}, and    
 "aSize" ==> an Array of two numbers of Pixels {"nWidth", "nHeight"}.   *
**************************************************************************
LOCAL nSetOrGet := iif(aArea == NIL, SPI_GETWORKAREA, SPI_SETWORKAREA)
LOCAL nSetFlag  := iif(aArea == NIL, 0, SPIF_SENDCHANGE)
LOCAL nLeft     := iif(aArea == NIL, 0, aArea[1])
LOCAL nTop      := iif(aArea == NIL, 0, aArea[2])
LOCAL nRight    := iif(aArea == NIL, 0, aArea[3])
LOCAL nBottom   := iif(aArea == NIL, 0, aArea[4])
LOCAL cBuffer   := iif(aArea == NIL, Space(16), U2Bin(nLeft) + U2Bin(nTop) + U2Bin(nRight) + U2Bin(nBottom))
LOCAL aPos      := {0, 0}
LOCAL aSize     := GetDeskTopSize()
   DllCall("User32.DLL", DLL_STDCALL, "SystemParametersInfoA", nSetOrGet, 0, @cBuffer, nSetFlag)
   nLeft    := Bin2U(substr(cBuffer,  1, 4))
   nTop     := Bin2U(substr(cBuffer,  5, 4))
   nRight   := Bin2U(substr(cBuffer,  9, 4))
   nBottom  := Bin2U(substr(cBuffer, 13, 4))
   aPos[1]  := nLeft
   aPos[2]  := aSize[2] - nBottom
   aSize[1] := nRight   - nLeft
   aSize[2] := nBottom  - nTop
return ({aPos, aSize})

Function HideWindowsTaskbar(lHide)
LOCAL nShowIt := iif(lHide, TOGGLE_HIDEWINDOW, TOGGLE_UNHIDEWINDOW)
LOCAL nHandle := FindWindow('Shell_traywnd', '')
LOCAL lResult := .f.
   if nHandle # 0
      lResult := (DllCall("User32.DLL", DLL_STDCALL, "SetWindowPos", nHandle, 0, 0, 0, 0, 0, nShowIt) # 0)
   endif
return (lResult)

Hope that helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net
Andreas Gehrs-Pahl
Re: Taskbar-size
on Fri, 17 Apr 2015 18:43:54 -0400
Thomas,

I forgot to include the FindWindow() function. Here it is:

Function FindWindow(cClassName, cTitle)
return (DllCall("User32.dll", DLL_STDCALL, "FindWindowA", cClassName, cTitle))

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net
Thomas PoolRe: Taskbar-size
on Mon, 20 Apr 2015 23:03:23 +0200
Hello Andreas,

Thanks for code!
When compiling, another function is missing: GetDeskTopSize()...
Can it be replaced by AppDeskTop():currentsize() ?

Kind regards, Thomas 


Op Fri, 17 Apr 2015 18:43:54 -0400 schreef Andreas Gehrs-Pahl:

> Thomas,
> 
> I forgot to include the FindWindow() function. Here it is:
> 
> Function FindWindow(cClassName, cTitle)
> return (DllCall("User32.dll", DLL_STDCALL, "FindWindowA", cClassName, cTitle))
> 
> Andreas
Andreas Gehrs-Pahl
Re: Taskbar-size
on Tue, 21 Apr 2015 04:46:15 -0400
Thomas,

>When compiling, another function is missing: GetDeskTopSize()...

Sorry, I overlooked that one.

>Can it be replaced by AppDeskTop():currentsize() ?

As a workaround, AppDeskTop():CurrentSize() will work, but this value isn't 
updated, when the Desktop resolution is changed (by the user). So, using the 
following function is the preferred method to get the current Desktop size:

Function GetDeskTopSize()
*************************************************************************
* Used to get the actual, current Desktop Size, as this value is not    
 updated correctly, if the Deskop resolution is changed during program 
 execution, and "AppDektop():CurrentSize() always reports the original 
 settings. See also PDR 109-4244 for details.                          *
*************************************************************************
LOCAL nHWnd   := AppDesktop():GetHWnd()
LOCAL nWidth  := 0
LOCAL nHeight := 0
LOCAL cBuffer := U2Bin(0) + U2Bin(0) + U2Bin(nWidth) + U2Bin(nHeight)
   DllCall("User32.DLL", DLL_STDCALL, "GetClientRect", nHWnd, @cBuffer)
   nWidth    := Bin2U(substr(cBuffer,  9, 4))
   nHeight   := Bin2U(substr(cBuffer, 13, 4))
return ({nWidth, nHeight})

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas.GP@Charter.net
web:   http://www.Aerospace-History.net
Thomas PoolRe: Taskbar-size
on Wed, 22 Apr 2015 13:26:02 +0200
Thanks again, Andreas!


Op Tue, 21 Apr 2015 04:46:15 -0400 schreef Andreas Gehrs-Pahl:

> Thomas,
> 
>>When compiling, another function is missing: GetDeskTopSize()...
> 
> Sorry, I overlooked that one.
> 
>>Can it be replaced by AppDeskTop():currentsize() ?
> 
> As a workaround, AppDeskTop():CurrentSize() will work, but this value isn't 
> updated, when the Desktop resolution is changed (by the user). So, using the 
> following function is the preferred method to get the current Desktop size:
> 
> Function GetDeskTopSize()
> *************************************************************************
> * Used to get the actual, current Desktop Size, as this value is not    *
> * updated correctly, if the Deskop resolution is changed during program *
> * execution, and "AppDektop():CurrentSize() always reports the original *
> * settings. See also PDR 109-4244 for details.                          *
> *************************************************************************
> LOCAL nHWnd   := AppDesktop():GetHWnd()
> LOCAL nWidth  := 0
> LOCAL nHeight := 0
> LOCAL cBuffer := U2Bin(0) + U2Bin(0) + U2Bin(nWidth) + U2Bin(nHeight)
>    DllCall("User32.DLL", DLL_STDCALL, "GetClientRect", nHWnd, @cBuffer)
>    nWidth    := Bin2U(substr(cBuffer,  9, 4))
>    nHeight   := Bin2U(substr(cBuffer, 13, 4))
> return ({nWidth, nHeight})
> 
> Andreas