Finding the height of the desktop tool bar

BlitzPlus Forums/BlitzPlus Programming/Finding the height of the desktop tool bar

julianbury(Posted 2010) [#1]
How can I find the height of the desktop tool bar in order to avoid obscuring it?

I know there is some Windows code for this but I have no idea of how to access it and use it.

Can anyone help?

Thank you for your kind attention :-)


Serpent(Posted 2010) [#2]
Do you mean the task bar?


julianbury(Posted 2010) [#3]
Yes, I guess I do. The task bar :-)


Serpent(Posted 2010) [#4]
Does BlitzPlus support user-declared-functions? I'm a Blitz3D user and not sure...


julianbury(Posted 2010) [#5]
Yes, if you mean something like ...

Function return_this()
work out something
return some_result
End function

(-_-)


xlsior(Posted 2010) [#6]
You'll have to use the windows API to obtain that info...

Kind of similar to this:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1311

(I don't know what the call is to get the system properties that you're looking for, though)


Serpent(Posted 2010) [#7]
Sorry, I wasn't very clear. The (-_-) was appropriate :P
What I was asking about is if BlitzPlus supports 'userlibs' - i.e. if it allows you to declare external functions from dlls.
Yes, you will need to use Windows API functions to find out these sorts of values. I'll assume the BlitzPlus has 'userlibs' (i.e. lets you declare these functions) for the rest of this post.

The function you will probably have is use is SystemParametersInfo (see MSDN PAGE HERE).

The thing you can Ctrl-F for on that page is "SPI_GETWORKAREA":
Retrieves the size of the work area on the primary display monitor.
The work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars.
The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates.


This looks like what you want - the rectangle of the screen not obscured by taskbars, toolbars, etc.

It says that you will need to use a RECT structure for this option. This will simply be a type in blitz:
Type RECT
  Field left
  Field top
  Field right
  Field bottom
End Type


The function:
BOOL WINAPI SystemParametersInfo(
  __in     UINT uiAction,
  __in     UINT uiParam,
  __inout  PVOID pvParam,
  __in     UINT fWinIni
);


You should probably need to use it like this:
Success = SystemParametersInfo(SPI_GETWORKAREA, 0, MyRECT, 0)
Afterwards, MyRECT should be filled with the data and Success will indicate whether the function was successful or not. Example:

Const SPI_GETWORKAREA = $30

Type RECT
	Field left
	Field top
	Field right
	Field bottom
End Type

Local MyRECT.RECT
MyRECT = New RECT

Print SystemParametersInfo(SPI_GETWORKAREA, 0, MyRECT, 0)
Print MyRECT\left
Print MyRECT\top
Print MyRECT\right
Print MyRECT\bottom

WaitKey
End


This works on my PC fine - but in Blitz3D. You'll need this in your userlibs (if they're supported in BlitzPlus):
.lib "user32.dll"
SystemParametersInfo%(uiAction%, uiParam%, pvParam*, fWinIni%) : "SystemParametersInfoA"



Hope this helps.
And if BlitzPlus doesn't support userlibs, tell me if it has CallDLL.


xlsior(Posted 2010) [#8]
What I was asking about is if BlitzPlus supports 'userlibs' - i.e. if it allows you to declare external functions from dlls.


Yes, it does.


Serpent(Posted 2010) [#9]
Okay - what I've described above should also work in BlitzPlus then.


julianbury(Posted 2010) [#10]
Hi Serpent :-)

BlitzPlus does, indeed support userlibs.
It has a directory of that name with a demo in it.
My reading of the contents indicates that the DLLs are C compilations.
I do not have a C compiler.
There is a file, 'demolib.decls' which I assume is short for demolib.declarations.
It's contents are as follows:
-------------------------------------------------------------------------

;Declarations file for demolib.dll
;
;Adds the following commands:
;
;DemoLib_InvertBits( bank,offset,count )
;DemoLib_ShuffleString$( str$ )

.lib "demolib.dll"

DemoLib_InvertBits( bank*,offset,byte_count):"_InvertBits@12"
DemoLib_ShuffleString$( str$ ):"_ShuffleString@4"

There is also a file, 121 lines long, called 'UserLibs.txt'.

I don't suppose it would dammage anything to present it to you, so here it comes ...

-------------------------------------------------------------------------

New DLL interface spec
----------------------

There is now a directory in the root blitzpath called 'userlibs'.

By adding DLLs and '.decls' files to this directory, you can extend blitz's command set.

DLLs contain actually library code, while .decls files contain 'declarations' to be added to the
base command set. These declarations describe the functions contained in the Dll.


Format of decls files
---------------------

Decls files should always start with a '.lib' directive, followed by the quoted name of the DLL to be
loaded, eg:

.lib "mylib.dll"

Following the .lib is a list of function declarations. The syntax of these is identical to
function declarations in Blitz, with the following exceptions:

* No default parameter values are allowed.

* If no function return type is specified, the function is a 'void' function - ie: it returns nothing.

* Instead of object parameters, you can only specify 'void*' parameters using a '*' type tag. Such
parameters can be assigned ANY object or bank, so BE CAREFUL!

* A declaration may be optionally followed by a 'decorated name'. This takes the form of a ':'
followed by a quoted string denoting the decorated name, eg:

MyFunction( text$ ):"_MyFunction@4"
MessageBox%( hwnd,text$,title$,style ):"MessageBoxA"

The decorated name is the name of the function as it appears in the dll, and only needs to be
specified if it is different from the actual function name.


Writing DLLs
------------

All functions MUST use the _stdcall calling convention.

Floats are passed and returned as per standard C/C++ conventions.

Strings are passed and returned in 'C' format - ie: a pointer to a null-terminated sequence of
characters.

Returned strings must be in a 'static' memory buffer. Once the function returns, this string is
immediately copied into an internal Blitz style string, so its OK to share this buffer between
multiple functions.

Both banks and objects can be passed to functions. The value passed is the address of the first byte
of storage. No information is sent regarding the size or type of memory passed so, again, BE CAREFUL!

Neither Banks or objects can be returned from functions.

Arrays are not supported at all.

VisualC decorates symbols quite heavily! If you are coding in 'C', the necessary stdcall specifier
will cause a '_' to be prepended, and a '@' (followed by the number of bytes passed to the function
- ie: number of parameters*4) to be appended. So, something like: 'void _stdcall MyFunc( int x )'
will end up as '_MyFunc@4'. In C++, the name decoration is even messier! But you can supress it by
using the 'extern "C"' feature (see examples below) so you're just left with the 'C' stdcall mess.

Other languages such as Delphi and Purebasic don't appear to suffer from this feature, but it can be
worthwhile looking through dll symbols if you're having problems. Check out PEview at
http://www.magma.ca/~wjr Open your dll and select 'SECTION .rdata'/'EXPORT address table'
to have a look at the exported symbols your compiler has seen fit to bestow upon your dll.

Example
-------

Ok, here's a little C++ example, as it would appear in VisualC.

First, we write the DLL:

//demo.dll
//
#include <math.h>
#include <string.h>
#include <stdlib.h>

#define BBDECL extern "C" _declspec(dllexport)
#define BBCALL _stdcall

//returns a float and has 6 float parameters
BBDECL float BBCALL VecDistance( float x1,float y1,float z1,float x2,float y2,float z2 ){
float dx=x1-x2,dy=y1-y2,dz=z1-z2;
return sqrtf( dx*dx+dy*dy+dz*dz );
}

//returns a string and has one string parameter
BBDECL const char * BBCALL ShuffleString( const char *str ){
static char *_buf;

int sz=strlen(str);

delete[] _buf;
_buf=new char[ sz+1 ];
strcpy( _buf,str );

for( int k=0;k<sz;++k ){
int n=rand()%sz;
int t=_buf[k];_buf[k]=_buf[n];_buf[n]=t;
}

return _buf;
}
After building this, the resultant 'demo.dll' should be placed in the userlibs directory.

Now, we also need to create a 'demo.decls' file, describing the functions in our dll. This file
is also placed in the userlibs directory:

.lib "demo.dll"
VecDistance#( x1#,y1#,z1#,x2#,y2#,z2# ):"_VecDistance@24"
ShuffleString$( str$ ):"_ShuffleString@4"

...Voila! The next time Blitz is started up, the new commands appear within the IDE and can be used.


Serpent(Posted 2010) [#11]
What you need to do is create a new text file in that directory. Then put in it:
.lib "user32.dll"
SystemParametersInfo%(uiAction%, uiParam%, pvParam*, fWinIni%) : "SystemParametersInfoA"

Once you've saved it, you need to change the file extension to '.decls'
The filename can be anything, as long as the extension is right.

Then, the code I posted above should work. When you compile your program, Blitz will recognise the function SystemParametersInfo just like one of the inbuilt ones.

What the '.decls' file actually does is tell Blitz where to find the function. There are various dlls that Windows has, all with a variety of functions for getting information about the computer, creating and controlling windows, creating processes, and more. The .decls file will tell Blitz that when you type "SystemParametersInfo", you want it to get the function out of 'user32.dll'.
The stuff in C++ is an example dll you can create. Once you compile the code with a C++ compiler, you can create a dll that your Blitz program can access just like it can access the Windows dll 'user32'.

I hope this explains everything.


julianbury(Posted 2010) [#12]
Thank you Serpent,

That's absolutly brilliant :D

Sorry about the delayed responce, duties keep interrupting the flow.

I need to take a sabatical to get stuck in and finish some of these projects.

(^_^)


TAS(Posted 2011) [#13]
My thanks to Serpent too, having the taskbar hide the bottom part of the game window has been the bane of my programming life.


TAS(Posted 2011) [#14]
The call also works with banks if you don't want to create a single use Type. It appears it also with any type structure as long as the first four fields are integers.

bnk=CreateBank(16)

Print SystemParametersInfo($30,0,bnk,0)
Print PeekInt(bnk,0)
Print PeekInt(bnk,4)
Print PeekInt(bnk,8)
Print PeekInt(bnk,12)
WaitKey()
End