Creating Custom Mouse Pointers

BlitzMax Forums/MaxGUI Module/Creating Custom Mouse Pointers

gameshastra(Posted 2007) [#1]
Hi,
How can I change the mouse pointer to take a custom bitmap as input and not one of the predefined values. I am using MaxGUI Any help will be greatly appreciated.
Regards,
D.Ramesh


Brucey(Posted 2007) [#2]
You can't, currently, without doing it via a system API.


GfK(Posted 2007) [#3]
Please don't post the same question in multiple forums. Its really annoying.


LAB[au](Posted 2007) [#4]
I agree with Gfk, it's really annoying.


gameshastra(Posted 2007) [#5]
If it can't be done without a system API, what is the system API to use ?


Brucey(Posted 2007) [#6]
According to my MSDN Library, LoadCursor, LoadImage and SetCursor might get you up and running.

Someone else might be able to help you more. I don't do Windows... :-)


... although it's almost tempting to build a little cross-platform module to do it... (but no.. I won't this time! :-p)


SebHoll(Posted 2007) [#7]
although it's almost tempting to build a little cross-platform module to do it

Please, please, please... :-( This would be really useful and I can't see Skid having the time to add this anytime soon. I wish I had the know-how to implement system API features into a module myself - I only know a bit about using MSDN but that's about it.

When I posted in MaxGUI bug reports about missing cursors on Mac OS X, you suggested I try to make my own etc, so I attempted to understand the Cocoa API and failed miserably - the only Mac I own is an old G3 running through VNC - so it's very ssllllooooowwwwww.

Also, how's your Console GUI mod going along - I saw you writing about it in your Worklogs but it looks like you've abondoned it.


Brucey(Posted 2007) [#8]
Tsk... cross/off topic chatter. Shame on you Seb ;-)

Okay... I could have a look at it (a custom pointer mod), but I can't promise anything very soon. I already have a cross-platform thing for mouse screen location (see bottom of gtkgui.bmx for example), so I guess it goes together...

looks like you've abondoned it.

You mean cuz I haven't mentioned it in my worklog for 15 days? (so this is what it's like to be Mark!) lol ;-)
I got side-tracked... as I often seem to. Fear not. It's very much alive. And now that (the surprise) Portmidi mod is almost ready, I can get back to it.


SebHoll(Posted 2007) [#9]
Whoops, I've done it again...
Tsk... cross/off topic chatter. Shame on you Seb ;-)

Sorry... (sniff, sniff) :-(

You mean cuz I haven't mentioned it in my worklog for 15 days? (so this is what it's like to be Mark!) lol ;-)
I got side-tracked... as I often seem to. Fear not. It's very much alive. And now that (the surprise) Portmidi mod is almost ready, I can get back to it.

Ooops, I should be infamous for how I word things badly. I wrote a post entitled "What is it with MaxGUI?" that (as you can imagine) ended badly too... Note to self, think before typing... I'm really appreciative of your work for the community, I think I may have to donate again when I get paid as a way of saying Thanks. ;-)


Brucey(Posted 2007) [#10]
Okay... so I have a working win32 (based on current win32maxgui) code that lets you customize your mouse pointer.
(Like I had nothing better to do over lunch :-p)

Bit scruffy... since it uses some C to do the nitty gritty, but it was easier to get it working that way. (Don't ask me why, I don't do Windows :-p)

Example
SuperStrict

Framework BRL.MaxGUI
Import BRL.Win32MaxGUI
Import BRL.EventQueue


Import "win32glue.cpp"

Extern
	Function SetCustomPointer(name:Byte Ptr)
End Extern

Local window:TGadget = CreateWindow("My Window",40,40,320,240)

' a bitmap, cursor or icon file....
SetCustomPointer("example.ico")

While True
	WaitEvent 
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
	End Select
Wend


The GLUE - win32glue.cpp
#include "win32gui/win32hwnd.h"

extern "C" {

void SetCustomPointer(char * file);

}

void SetCustomPointer(char * file) {

	bbSetCursor((HCURSOR)LoadImage( 0, (LPCTSTR) file, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE | LR_SHARED));
	
}



Really wants to be cross-platform friendly... but here ya are anyways...

And I only tested it briefly with a couple of icon and cursor files... so your mileage may vary.


You may thank, in order of appearance... MSDN Library, Google, and Me. :-p


Brucey(Posted 2007) [#11]
almost working on the Mac now.... changes to my custom pointer, then changes back to normal... not worked out why it's doing that yet.
Still, nice to see it change (albeit it for a moment ;-)


SebHoll(Posted 2007) [#12]
Thanks Brucey. This is a great help. Btw, I suggest you check your PayPal account - I've sent it to the same address as last time ;-) .


Brucey(Posted 2007) [#13]
Hah.... it's doing the same for SetPointer.... :-p

(not that that is a good thing)


Brucey(Posted 2007) [#14]
thanks man, but you didn't have to ;-)

Righty... this is *very* hacky, and I generally don't like to release things in such a state... but just to prove that it can be done....

For Mac OSX :

Example
SuperStrict


Framework BRL.MaxGUI
Import BRL.CocoaMaxGUI
Import BRL.EventQueue
Import BRL.Pixmap
Import BRL.PNGLoader

Import "cocoaglue.m"

Extern
	Function NSPixmapImage:Int(image:TPixmap)
	Function NSNewCursor:Int(image:Int)
	Function NSSetCursor(cursor:Int)
End Extern


Local window:TGadget = CreateWindow("My Window",40,40,320,240)
Local button:TGadget = CreateButton("Click Me!", 20, 20, 100, 28, window)

While True
	WaitEvent 
	Select EventID()
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_GADGETACTION
			SetCustomPointer("example.png")
	End Select
Wend

Function SetCustomPointer(file:String)
	Global pix:TPixmap
	Global img:Int
	Global cursor:Int
	
	pix = LoadPixmap(file)
	img = NSPixmapImage(pix)
	cursor = NSNewCursor(img)
	
	NSSetCursor(cursor)
	
End Function


cocoaglue.m

#include <AppKit/AppKit.h>

NSCursor * NSNewCursor(NSImage * image) {
	NSCursor * cursor;
	cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0,0)];
	[cursor retain];
	return cursor;
}

void NSSetCursor(NSCursor * cursor) {

	[cursor set];

}


It really wants done properly... with managed variables and the like (ie. this is leaky) - this is a dirty hack after all...

Make yourself a png with transparency (up to 64x64 I believe), and load it in there...

Enjoy ;-)


SebHoll(Posted 2007) [#15]
thanks man, but you didn't have to ;-)

Don't mention it - you've earnt it a hundred times over...

Thanks for having a shot at the custom cursors, I'll have a go trying to use it when I get a moment. Btw, are these leaks severe enough to worry about?


Brucey(Posted 2007) [#16]
Well, it's creating an NSImage and NSCursor that are never cleaned up...

Ideally, it'd probably cache everything and the next time you tried to set one, it would re-use it. As it stands, it'll get one fresh, and the old data will be hanging around.


gameshastra(Posted 2007) [#17]
Thanks for the posts, I will check up on the win32glue code.
Presently I got it working using HideMouse() Followed by DrawImage()
Many Thanks,
D.Ramesh


Brucey(Posted 2007) [#18]
Ahhh... on a Canvas/Graphics window... So not really a MaxGUI problem after all then...


gameshastra(Posted 2007) [#19]
How do I compile the C++ code?


SebHoll(Posted 2007) [#20]
How do I compile the C++ code?

On Windows, you need to have MinGW (a small C++ compiler) set up and installed. See this sticky (or this sticky if you have Vista). Then you just create the files, and Import "filename.cpp" them as you would any other file/module.


gameshastra(Posted 2007) [#21]
I have installed and configured mingw the win32hwnd.h file is not there. Also how do you set the include and library paths for the mingW compiler?

Regards,
Ramesh D


gameshastra(Posted 2007) [#22]
I got these errors when I compiled the code
uilding curstest
Compiling:win32glue.cpp
C:/projects/etchasketch/code/win32glue.cpp:1:32: win32gui/win32hwnd.h: No such file or directory
C:/projects/etchasketch/code/win32glue.cpp: In function `void SetCustomPointer(char*)':
C:/projects/etchasketch/code/win32glue.cpp:11: error: `HCURSOR' undeclared (first use this function)
C:/projects/etchasketch/code/win32glue.cpp:11: error: (Each undeclared identifier is reported only once for each function it appears in.)
C:/projects/etchasketch/code/win32glue.cpp:11: error: `bbSetCursor' undeclared (first use this function)
C:/projects/etchasketch/code/win32glue.cpp:13:2: warning: no newline at end of file
Build Error: failed to compile C:/projects/etchasketch/code/win32glue.cpp
Process complete


SebHoll(Posted 2007) [#23]
Brucey's code requires MaxGUI to run, as it is Windows MaxGUI module that contains the win32hwnd.h file.

I suggest you change the import in the win32glue.cpp file to...

#include "C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.h"
This really isn't a very nice way to do it (as it as an absolute file path), but seeing as this code is only preliminary work and doesn't exist as a module in its own right, you'll have to work around it. This should be fixed if Brucey decides to release a specific module for this custom cursor code.


gameshastra(Posted 2007) [#24]
I have Blitzmax demo and there is no such file as win32hwnd.h

Ramesh


Brucey(Posted 2007) [#25]
:o)


... how's about

1) Buy BlitzMax
2) Buy MaxGUI for BlitzMax

It may help...


gameshastra(Posted 2007) [#26]
We have purchased blitzmax but not maxgui but we will be doing it soon


gameshastra(Posted 2007) [#27]
I have got BlitzMax I have also purchased MaxGUI yesterday. I am getting a whole lot of errors compiling the example given by brucey

Building curstest
Compiling:win32glue.cpp
In file included from C:/Program Files/BlitzMax/mod/brl.mod/blitz.mod/blitz.h:5,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/../gui/../blitzplus.h:5,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/../gui/event.h:5,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.h:18,
from C:/projects/etchasketch/code/win32glue.cpp:1:
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:5:19: ctype.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:6:19: stdio.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:7:20: string.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:8:20: stdlib.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:9:20: stdarg.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:10:20: assert.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:11:22: sys/stat.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:12:18: time.h: No such file or directory
C:/Program Files/BlitzMax/mod/pub.mod/stdc.mod/stdc.h:24:21: direct.h: No such file or directory
In file included from C:/Program Files/BlitzMax/mod/brl.mod/maxgui.mod/maxgui.h:4,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/../gui/event.h:7,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.h:18,
from C:/projects/etchasketch/code/win32glue.cpp:1:
C:/Program Files/BlitzMax/mod/brl.mod/system.mod/system.h:14:22: windows.h: No such file or directory
In file included from C:/Program Files/BlitzMax/mod/brl.mod/maxgui.mod/maxgui.h:4,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/../gui/event.h:7,
from C:/Program Files/BlitzMax/mod/brl.mod/win32maxgui.mod/win32gui/win32hwnd.h:18,
from C:/projects/etchasketch/code/win32glue.cpp:1:
C:/Program Files/BlitzMax/mod/brl.mod/system.mod/system.h:15: error: variable or field `bbSystemEmitOSEvent' declared void
C:/Program Files/BlitzMax/mod/brl.mod/system.mod/system.h:15: error: `HWND' was not declared in this scope

......

What could the problem be

Awaiting your reply
Ramesh


Brucey(Posted 2007) [#28]
You need to install MinGW as Seb mentions above...

http://www.blitzmax.com/Community/posts.php?topic=53442


gameshastra(Posted 2007) [#29]
I have installed mingw file name: MinGW-3.1.0-1.exe as stated by you.
I installed mingw to c:\mingw and set the environment variable
MINGW to C:\mingw
and in the path included c:\mingw\bin
on my windows XP system
I am getting a whole lot of errors as above in compiling the c++ code given by brucey above

Please let me know what I should do

Regards,
D.Ramesh