This is my analyse :

When reading Java source code, it is obvious that on Windows, Java does not use System resources.

">

(original) (raw)

Dear all,

When developping a Swing client, I face the following problem :
When setting the hand cursor on Windows, I noticed that the default system cursor was not used.

I analysed the problem and found the rrot cause.
I also made a correction and tested it on Windows 7.

This is my analyse :

When reading Java source code, it is obvious that on Windows, Java does not use System resources.

In the code (from jdk\\src\\windows\\native\\sun\\windows\\awt\_Cursor.cpp�) bellow :

AwtCursor \* AwtCursor::CreateSystemCursor(jobject jCursor)

{

��� JNIEnv \*env = (JNIEnv \*)JNU\_GetEnv(jvm, JNI\_VERSION\_1\_2);

��� jint type = env->GetIntField(jCursor, AwtCursor::typeID);

��� DASSERT(type != java\_awt\_Cursor\_CUSTOM\_CURSOR);

��� LPCTSTR winCursor;

��� switch (type) {

����� case java\_awt\_Cursor\_DEFAULT\_CURSOR:

����� default:

������� winCursor = IDC\_ARROW;

������� break;

����� case java\_awt\_Cursor\_CROSSHAIR\_CURSOR:

������� winCursor = IDC\_CROSS;

������� break;

\[�\]

����� case java\_awt\_Cursor\_HAND\_CURSOR:

������� winCursor = TEXT("HAND\_CURSOR");

������� break;

����� case java\_awt\_Cursor\_MOVE\_CURSOR:

������� winCursor = IDC\_SIZEALL;

������� break;

��� }

��� HCURSOR hCursor = ::LoadCursor(NULL, winCursor);

��� if (hCursor \== NULL) {

������� /\* Not a system cursor, check for resource. \*/

������� hCursor = ::LoadCursor(AwtToolkit::GetInstance().GetModuleHandle(),

������������������������������ winCursor);

��� }

��� if (hCursor == NULL) {

������� hCursor = ::LoadCursor(NULL, IDC\_ARROW);

������� DASSERT(hCursor != NULL);

��� }

��� AwtCursor \*awtCursor = new AwtCursor(env, hCursor, jCursor);

��� setPData(jCursor, ptr\_to\_jlong(awtCursor));

��� return awtCursor;

}

In the case of the HAND\_CURSOR (in red), �Java will try to load the cursor from the system (in blue).

If it fails (hCursor == NULL) then it will try to load the cursor from its own resource (in orange) :

hCursor = ::LoadCursor(AwtToolkit::GetInstance().GetModuleHandle(),

������������������������������ winCursor);

In our case, if we check in the AWTToolkit module resources, in jdk\\src\\windows\\native\\sun\\windows\\awr.rc, we find the following content :

#include "windows.h"

// Need 2 defines so macro argument to XSTR will get expanded before quoting.

#define XSTR(x) STR(x)

#define STR(x)� #x

LANGUAGE LANG\_NEUTRAL, SUBLANG\_NEUTRAL

HAND\_CURSOR� CURSOR� DISCARDABLE "hand.cur"

AWT\_ICON���� ICON��� DISCARDABLE "awt.ico"

CHECK\_BITMAP BITMAP� DISCARDABLE "check.bmp"

And we find that java.exe embed its own hand cursor, in jdk\\src\\windows\\native\\sun\\windows\\hand.cur : The �famous� hand that it is displayed instead of our system cursor.


This is the correction :

, I made the correction into the JRE source code�:

����� case java\_awt\_Cursor\_HAND\_CURSOR:

������� /\* MLM change winCursor = TEXT("HAND\_CURSOR"); \*/

������� winCursor = IDC\_HAND;�����

������� break;

I could compile and regenerate a JRE with this change :

D:\\Work\\Current\\openjdk\\build\\windows-amd64\\bin>java \-version

openjdk version "1.7.0-u6-unofficial"

OpenJDK Runtime Environment (build 1.7.0-u6-unofficial-b24)

OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)

And this works !

If I change the hand cursor at System level, Java takes it into account.

Last but not least question:

Why did a Sun developper, one day :�winCursor = TEXT("HAND\_CURSOR");

This seems so not consistent with other part of the code... So there is probably a good reason. Perhaps the hand cursor was not existant on Windows platform when this was done ?


Regards


Morvan