Way to detect window position on Mac?

BlitzMax Forums/BlitzMax Programming/Way to detect window position on Mac?

Grey Alien(Posted 2007) [#1]
Hi (again), now I'm trying to find out how to get the position of a Graphics Window (created with Graphics 800,600,0) on a Mac.

On the PC I call GetWindowRect from the Win API and this returns a Rect that I can read the coords from.

To get the client area I also use GetWindowInfo from the Win API which returns a TWindowInfo structure which contains the client area coords.

It would be really handy to have similar functions in Mac OSX so that I can get the mouse coords relative to the desktop then slide the mouse cursor in/out of the Graphics Window which has know coords relative to the desktop.

Anyone know how to do it? OR perhaps know of a website which has detail about the API calls that can be made, an equivalent of MSDN? Many thanks!


Perturbatio(Posted 2007) [#2]
if my other code worked, then this might also:




Grey Alien(Posted 2007) [#3]
Hmm, again I think it nearly works. It compiles and runs but I don't seem to be able to use the returned theOrigin properly (when I try to Print theOrigin.X the app just crashes even in debug mode). I looked up NSPoint on developer.apple.com and it is simply a struct with x and y fields as FLOATS, nothing else.

Here's what I have so far:

This file is called cocoamouse.m
#include <AppKit/AppKit.h>

void ccNSGetCursorPos(int *x,int *y){
	NSPoint mouseLoc = [NSEvent mouseLocation];
	*x = mouseLoc.x;
	*y = mouseLoc.y;
}

int getActiveWindowOSX(){
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    NSApplication *myApp;
    myApp=[NSApplication sharedApplication];
    NSWindow *myWindow = [myApp keyWindow];
    [pool release];
//    return *NSWindow;
}

NSPoint ccGetWindowOrigin(){
    NSApplication *myApp = [NSApplication sharedApplication];
    NSWindow *myWindow = [myApp keyWindow];
    NSRect myFrame = [myWindow frame];
    NSPoint theOrigin = myFrame.origin;
    return theOrigin;
};


And here is my test code:

SuperStrict

Import "cocoa_mouse.m"

Extern
	Function ccNSGetCursorPos(x:Int Ptr, y:Int Ptr)
	Function ccGetWindowOrigin: TAccuratePoint()
End Extern

Type TAccuratePoint
	Field X#
	Field Y#
End Type

Function GetScreenPointerPos(x:Int Var, y:Int Var)
	ccNSGetCursorPos(Varptr x, Varptr y)
End Function

Graphics 640,480, 0

While Not KeyDown(KEY_ESCAPE)

    Cls

    Local x:Int, y:Int
    GetScreenPointerPos(x, y)

    DrawText "Pos = " + x + ", " + y, 50, 50
	Local p:TAccuratePoint = ccGetWindowOrigin()
	Print p.x
    Flip

Wend

End


I tried this:

Function ccGetWindowOrigin: Bye Ptr()

but it wouldn't compile, said "Unable to convert from 'Byte Ptr' to 'TAccuratePoint'"

Any ideas? Thx.


Brucey(Posted 2007) [#4]
I don't think you want to be mix-and-matching c/max code like that. It's certainly not likely to work the way you think it will ;-)

Since you appear to be trying so hard to get this working...

your cocoa code:
void ccGetWindowOrigin(int * x, int * y){
    NSApplication *myApp = [NSApplication sharedApplication];
    NSWindow *myWindow = [myApp keyWindow];
    NSRect myFrame = [myWindow frame];
    *x = myFrame.origin.x;
    *y = myFrame.origin.y;
};

your max code :
Extern
	Function ccGetWindowOrigin(x:int ptr, y:int ptr)
End Extern

Type TAccuratePoint
	Field X#
	Field Y#
    Function Update:TAccuratePoint()
        Local this:TAccuratePoint = new TAccuratePoint
        ccGetWindowOrigin(varptr this.X, varptr this.Y)
        return this
    End Function

End Type


...

Local p:TAccuratePoint = TAccuratePoint.Update()

...


or something like that...

:o)


Grey Alien(Posted 2007) [#5]
Excellent yeah good one, forget returning the point, and return X and Y instead. Thanks Brucey!

The thing is, I've had good success in returning a TPoint from a Windows API call before, but it wasn't a return value it was passed in as a parameter (Byte Ptr), also the TPoint was two INTS not two floats so maybe that's why?

OK then, so NOW how to return the CLIENT AREA RECT of a window i.e. the CLIENT AREA ORIGIN and the CLIENT AREA SIZE. Any ideas dudes? I suppose the apple developer site may have some clues...


Grey Alien(Posted 2007) [#6]
Cool this works well, and it turns out that I don't need to know the client coords/area. I asked for that because in Windows, a normal window seems to have a border round it and also because the y coords start from the top you have to know where the client area begins AFTER the title bar which can vary height depending on user preferences.

However, on the Mac, because the coords are from the bottom there is no title bar to take into account and also there doesn't seem to be any border round the window. Unless you can CHANGE the window border in any of the MacOS options, anyone know if that's possible?

Here's the final code. When I've finalised this in the framework, I'll have to tweak the X and Y coords by a couple of pixels as if I point at the bottom corner of the window the coords don't quite match up...

cocoamouse.m
#include <AppKit/AppKit.h>



void macGetCursorPos(int *x,int *y){

	NSPoint mouseLoc = [NSEvent mouseLocation];

	*x = mouseLoc.x;

	*y = mouseLoc.y;

}



int macGetActiveWindow(){

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

    NSApplication *myApp;

    myApp=[NSApplication sharedApplication];

    NSWindow *myWindow = [myApp keyWindow];

    [pool release];

//    return *NSWindow;

}



void macGetWindowOrigin(int * x, int * y){
    NSApplication *myApp = [NSApplication sharedApplication];
    NSWindow *myWindow = [myApp keyWindow];
    NSRect myFrame = [myWindow frame];
    *x = myFrame.origin.x;
    *y = myFrame.origin.y;
}


main code:
Strict

Import "cocoa_mouse.m"

Extern
	Function macGetCursorPos(x:Int Ptr, y:Int Ptr)
	Function macGetWindowOrigin(x:Int Ptr, y:Int Ptr)
End Extern

Type TPoint
	Field X
	Field Y
End Type

Function GetScreenPointerPos(x:Int Var, y:Int Var)
	macGetCursorPos(Varptr x, Varptr y)
End Function

Function GetWindowOrigin:TPoint()
	Local p:TPoint = New TPoint
     macGetWindowOrigin(Varptr p.X, Varptr p.Y)
     Return p
End Function

Graphics 640,480, 0

While Not KeyDown(KEY_ESCAPE)

    Cls

    Local x:Int, y:Int
    GetScreenPointerPos(x, y)

    DrawText "Mouse Pos  = " + x + ", " + y, 50, 50
	Local p:TPoint = GetWindowOrigin()
    DrawText "Window Pos = " + p.x + ", " + p.y, 50, 70
    Flip

Wend

End

Thanks to all for their help! :-)


Grey Alien(Posted 2007) [#7]
Hmm bit of problem. If the application is still running but not focused then the GetWindowOrigin returns 0,0 !

There must be a way to retain a handle to the main app window when it's first created and then use that to get the origin even when the app is not focused? (at least that's how I do it on the PC)

Perhaps by fixing macGetActiveWindow so that it returns a valid handle (which I capture as soon as the graphics window is created), and then passing that to a modified version of macGetWindowOrigin ?

Any ideas? thanks in advance.