Windows cursor size bigger than maximum available - java

I'm working with an application where one of the options which I have to develop is to change Windows 10 cursor size. In my case it its important to change cursor size for the whole windows, not only for a specific java application window. Currently I'm able to change size of specific cursor type by modifying Windows registry attributes under HKEY_CURRENT_USER → Control Panel → Cursors directory.
Unfortunately, I need to set cursor size bigger than 32x32px.
Somewhere I've found a solution where there was a possibility to cover existing mouse cursor by a bitmap and just follow the position of a cursor, but I don't know how to start with the implementation.
I searched on the Internet and I've found some applications that allow user to modify size of cursor for whole Windows 10—for example, this was CursorFX.
Do you know how to increase cursor size programmatically?

You can set any size cursor you want using the SetSystemCursor API. You are not limited to the SM_CXCURSOR/SM_CYCURSOR metrics (cf. GetSystemMetrics function)—those just tell you the system's default cursor size, which is typically 32×32 (or 48×48 on high-DPI systems). I know for a fact that this works as far back as Windows XP; I'm pretty sure it works further back than that.
The key lies in how you load the cursor resource. As you probably already know, you need an HCURSOR object to pass to SetSystemCursor. This is a handle-to-cursor, in Windows API speak. The obvious way to load a cursor is by calling the LoadCursor API function, but that is a very old function, introduced with 16-bit Windows and it is limited to loading cursors of size SM_CXCURSOR×SM_CYCURSOR. So you don't want that†; you want to call LoadImage, which as the documentation indicates is the modern replacement function. It takes an enumerated integer parameter indicating which type of image to load: IMAGE_BITMAP (0), IMAGE_ICON (1), IMAGE_CURSOR (2), or IMAGE_ENHMETAFILE (3). Obviously, IMAGE_CURSOR is what you want to use here.
You can either load from a cursor resource embedded into your application's binary (as a Win32 resource), or you can load from a *.CUR/*.ANI file from the disk. To do the latter, pass the LR_LOADFROMFILE flag to the LoadImage function.
I don't know Java, so I can't translate this to Java with whatever syntax is required there to make native Windows API calls, but here is the code in C:
// Load from a CUR file, at C:\LargeCursor.cur, with a size of 64x64 pixels
HCURSOR hCursor = (HCURSOR)LoadImage(NULL,
"C:\\LargeCursor.cur"),
IMAGE_CURSOR,
64, 64,
LR_DEFAULTCOLOR | LR_LOADFROMFILE);
assert(hCursor != NULL); // verify that load was successful
BOOL result = SetSystemCursor(hCursor, OCR_NORMAL);
assert(result != FALSE); // verify that the change was successful
// Load from an embedded resource, IDC_CURSOR, with a size of 64x64 pixels
HCURSOR hCursor = (HCURSOR)LoadImage(GetModuleHandle(NULL),
IDC_CURSOR),
IMAGE_CURSOR,
64, 64,
LR_DEFAULTCOLOR);
assert(hCursor != NULL); // verify that load was successful
BOOL result = SetSystemCursor(hCursor, OCR_NORMAL);
assert(result != FALSE); // verify that the change was successful
Note that the SetSystemCursor requires one of the OCR_* constants to identify which system cursor type to change. These aren't included by default when you include Windows.h; you have to define OEMRESOURCE before including Windows.h. I'm assuming, though, that with Java, you're just defining the constants yourself as enumerated values. In that case, they're all available in the MSDN documentation for SetSystemCursor. For example, OCR_NORMAL is 32512.
Notice, though, that what we're doing here is loading a new cursor (i.e., image) of the desired size, and then setting that. That works fine. What you can't easily do is just expand the size of the existing cursor glyph. To do that, you'd have to retrieve the current cursor glyph, draw it onto a bitmap, scale that bitmap to the desired size, convert that bitmap to an HCURSOR, and then set that HCURSOR using SetSystemCursor. And, naturally, the problem with that is Windows cursor glyphs are just bitmaps, so they're not infinitely scalable. You will start losing resolution quickly, so this is not recommended. If you need a large-size cursor, you will need to provide your own image.
By "CursorFX", I believe you're thinking of AniFX (by the same fellow, Attila Kovrig, who wrote IcoFX). This is a cursor image editor and would be a great way to create the *.CUR/*.ANI file(s) you need. But you could just as easily use some other piece of software designed for creating cursors; there are myriad to choose from.
__
† Not that you wanted that function with SetSystemCursor anyway, since SetSystemCursor destroys the specified cursor by calling DestroyCursor. You would need to do LoadCursor and then CopyCursor before calling SetSystemCursor. This is all spelled out in the documentation for SetSystemCursor, but as I said, you don't need to worry about this anymore because you just use LoadImage (without the LR_SHARED flag).

Related

Extract cursor size via WinAPI (Windows 10)

I need to extract the cursor image for using it in my swing application (Java).
Firstly, I found similar question, modified code snippet from an answer, and got this sandbox application.
Shortly, it gets cursor image via JNA and WinAPI, then shows this image on JFrame and sets custom cursor for this frame.
In most cases, this code works correctly and suits my tasks. But then I found that when the user changes the cursor's size or color(Windows 10 feature), the program extracts an invalid cursor image that matches the original cursor neither in color nor in size.
When the user has standard cursor:
When the user has e.g. pink cursor then bigger than standard one:
After this situation, I decided to do the same sandbox application, but via C++ and WinAPI. I used answers for this question, but solved only troubles with color.
I think the main bottleneck is that GetSystemMetrics function returns default cursor size (32x32) and it doesn't change after the cursor's size changing. I found some proves for this here, but I'm not sure.
So my question is:
How can I get the real size of cursor?
Thanks a lot in advance!
I think the main bottleneck is that GetSystemMetrics function returns
default cursor size (32x32) and it doesn't change after the cursor's
size changing.
When user change cursor size via Settings. System Settings will update this change to registry value CursorBaseSize under HKEY_CURRENT_USER\Control Panel\Cursors.
You can get notification when change happens via WM_SETTINGCHANGE or SetWinEventHook (EVENT_OBJECT_SHOW, OBJID_CURSOR).
Then read CursorBaseSize register value to get new size and get other information using GetIconInfoEx to creates a cursor having the specified size. (CreateCursor)
More references: How can I get notified when the cursor changes?
Thanks #Rita Han - MSFT for giving the initial point to start searching.
You can get a real cursor size in two ways:
The first way is mentioned before: we need to get value from registry value CursorBaseSize under HKEY_CURRENT_USER\Control Panel\Cursors.
The second way was found here: we can get cursor size multiplier form registry value CursorSize under HKEY_CURRENT_USER\Software\Microsoft\Accessibility and then calculate the cursor size yourself. It can be done somehow like this: newHeight = cursorHeight + (multiplier - 1) * (cursorHeight / 2); where cursorHeight is value from GetSystemMetrics(SM_CYCURSOR) and multiplier is value from the registry. The cursor real width value will be the same as newHeight. All values are unsigned long if we use C++.`
Both methods of finding the size lead to the same result.
If you need to find to get cursor real size value from the registry in Java, you can use Advapi32Util class from JNA-platform:
// Read an int (& 0xFFFFFFFFL for large unsigned int)
int baseSize = Advapi32Util.registryGetIntValue(
WinReg.HKEY_CURRENT_USER, "Control Panel\\Cursors", "CursorBaseSize");

Nice looking hand cursor with drop shadow? [duplicate]

I'd like to make a custom help cursor by "badging" the built-in default mouse cursor with a question mark when the user is hovering over an object that can be clicked for context-sensitive help. I'd like this to work nicely across platforms/look-and-feels (to look consistent with the white Windows mouse and the black Mac mouse, for instance.) Is there a way to get the cursor Image from the current Toolkit so that I could generate a combined Image to set as the cursor?
This question points out that the information can't be gotten from the Cursor object. There's also a comment there that suggested fishing around in the JRE, which I've also tried a bit: There and in google images, I didn't find any straightforwardly accessible graphics files to plunder
An alternative would be to add a mouseMoved listener and draw manually a little to the right of the cursor (on the parent, I suppose, to avoid clipping at the borders?) but I was a bit concerned about overhead, and in initial explorations, this was looking very complicated. I'd take other suggestions about finding or making a nice help cursor as well. (The hand is the best built-in, but it doesn't say "help" as clearly as a question-mark.)
In general, no. Most cursors are owned by the platform's host operating system, but a few live in $JAVA_HOME/lib/images/cursors/, for example:
$ ls -1 lib/images/cursors/
cursors.properties
invalid32x32.gif
motif_CopyDrop32x32.gif
motif_CopyNoDrop32x32.gif
motif_LinkDrop32x32.gif
motif_LinkNoDrop32x32.gif
motif_MoveDrop32x32.gif
motif_MoveNoDrop32x32.gif
I'm not sure this is the best solution in your case, because a good built-in mouse cursor should be the best. Anyway you can use mouse listeners and draw on a glasspane according to the mouse position. Here's a glasspane drawing example.
Java uses the default system cursor except for the Drag-and-Drop cursor, where it is using it's own cursors.
So for every cursors but DnD, refer to Extract cursor image in Java . JNA has to be used and can be easily added to any Maven project.
For DnD cursors, the solution from trashgod is good.
They can be loaded this way:
private static Path customSystemCursorPath = null;
public static Image loadDnDCursorImage(String cursorName) throws IOException {
if (customSystemCursorPath == null) {
String jhome = System.getProperty("java.home", "????");
customSystemCursorPath = Paths.get(jhome, "lib", "images", "cursors");
}
// TODO change this to retrieve the cursor filename from cursors.properties
cursorName = "win32_" + cursorName + "32x32.gif";
Path cursorPath = customSystemCursorPath.resolve(cursorName);
Image image = ImageIO.read(cursorPath.toFile());
return image;
}

How to change display settings programically with java?

Is it possible to alter (change/update) display settings (configuration) in Windows XP using Java programming language?
I would like to do something like this:
Display[] displays = WindowsXPSystem.getDisplays(); //get all available displays (monitors). assume there are currently two monitors connected
Display d0 = displays[0]; // the first is 24" and is positioned on the left
d0.setPrimary(true); // and it should be primary, so all new windows open on it.
d0.setSize(new Dimension(1920,1080)); //update screen size (resolution)
d0.setPossition(0,0); //and position it on the left
Display d1 = displays[1]; //second monitor is also present
d1.setSize(new Dimension(1440,768)); // and it's 14.1" laptop's display
d1.setPossition(1920,332); //it's positioned on the right
Any ideas/suggestions/APIs how to update display settings with Java?
I think this is not possible with plain Java. Have a look at this question here:
Detect and Change display resolution permanently using java
as stated there, it's maybe possible to use any native Libraries through JNI (Java Native Interface) which kind of wraps native Libraries. But you will loose your platform independency then.
There is no plain Java solution to your problem. The function is way to specific for a generic implementation.
You could however, if you really need to implement this use a JNI library, that wraps the Windows functionality of adjusting the screen resolution.

Getting the Java Swing 'No Drag' Cursor

Is it possible to get a reference to Swing "no Drag "Cursor ,since it is OS Specific, or maybe override it
I think you might be looking for the DragSource class which has bunch of predefined cursors.
I would look into java.awt.Toolkit::createCustomCursor if you want a cursor that is not predefined in java.awt.Cursor
public Cursor createCustomCursor(Image cursor,
Point hotSpot,
String name);
From the Java 6 Documentation:
Creates a new custom cursor object. If the image to display is invalid, the cursor will be hidden (made completely transparent), and the hotspot will be set to (0, 0).
Note that multi-frame images are invalid and may cause this method to hang.

Absolute keyboard input position (blinking cursor)

Is it possible to make Java program that will determine the absolute position (x,y on screen) of blinking keyboard cursor? That cursor can be in any text editor.
Not easily, since the position of a cursor on a screen of a program is merely a data point inside that program and rendering that cursor is a method running in the program. (I'm reading your question to mean that the program/editor in question is a wholly separate process from your Java program, right?)
You can theoretically do it if:
The program explicitly exports via some API calls the cursor location
You capture the actual screengrabs of that program very fast, analyze the image difference, and deduce cursor location from appearing/disappearing rectangle or short line in case the screen of the program didn't change save for cursor blink.
If you need relative (e.g. in # of chars instead of # of pixels) location in an editor, then somehow use edge recognition to detect editor size, some advanced image processing magic to deduce font size, and compute character-based offsets.
If the editor is using standard OS (e.g. Windows) APIs to draw both editing window AND the cursor, it might theoretically be plausible to hook into the system to intercept those calls - i don't posess nearly the amount of knowledge of what those APIs might be or if such even exist, how possible it is to intercept them, and whether Java programs are able to do that even if it's possible theoretically.
The question here is not whatever is possible or not, the question is for what purpose should i want to do this? Frankly, i don't see any reason, and i am sick of annoying mini-apps who act like spyware. Are u trying to duplicate the existent app into another form of mass terror?
I beg your pardon if u find my comment offensive, but this is my answer. Another question : why?

Categories

Resources