JNI & C & EVENTS

G

ginjasvinja

Hi all, I've already been here with similar topic but I need your help
again. I wrote the code that should be catch an event like "left button
of mouse clicked", using java JNI and C. I wrote it by following the
Desktop Indicator sample I've found on Internet. here is the code:

/*************************************Dogadjajava.java*******************************************/
import java.util.*;

public class Dogadjajava
{
private int handler = 0;
private Vector listeners = new Vector();

private native void nativeEnable() throws UnsatisfiedLinkError;
private native void nativeDisable() throws UnsatisfiedLinkError;
/**
* Loads the JNI library, if available.
*/
public static boolean initialize()
{
// Load JNI library
try
{
System.out.println("J: Dynamic Library should be Loaded\n");
System.load( "C:\\C++\\dogadjajC\\Debug\\dogadjajC.dll" );
System.out.println("J: Dynamic Library Loaded\n");
}
catch( UnsatisfiedLinkError x )
{
return false;
}

return true;
}


/**
* Creates a window.
**/
public Dogadjajava()
{
super();
System.out.println("J: Kontruktor Daogadajava\n");
}

/**
* Enables the window for events
*/
public void show()
{
System.out.println("J: show-call nativeEnable\n");
try
{
nativeEnable();
}
catch( UnsatisfiedLinkError x )
{
}
}

/**
* Hides the window for events
*/
public void hide()
{
System.out.println("J: hide-call nativeDisable\n");
try
{
nativeDisable();
}
catch( UnsatisfiedLinkError x )
{
}
}

/**
* Notifies all listeners that the desktop indicator was clicked.
**/
public void fireClicked()
{
Vector listenersClone = (Vector) listeners.clone();
DogadjajavaListener listener;
for( Enumeration e = listenersClone.elements(); e.hasMoreElements();
)
{
listener = (DogadjajavaListener) e.nextElement();
listener.onDogadjajClicked( this );
}
System.out.println("Kliknuli ste misem!\n");
}

public void addDogadjajavaListener( DogadjajavaListener listener )
{
listeners.addElement( listener );
}

public void removeDogadjajavaListener( DogadjajavaListener listener )
{
listeners.removeElement( listener );
}

}

/**************************************DogadjajavaListener.java*************************************/
public interface DogadjajavaListener
{
/**
* Called when something is clicked.
**/
void onDogadjajClicked( Dogadjajava source );
}

/**************************************DogadjajavaTest.java****************************************/
public class DogadjajavaTest implements DogadjajavaListener
{
static DogadjajavaTest listener;

static public void main( String args[] )
{
// Initialize JNI extension
if( !Dogadjajava.initialize() )
{
System.err.println( "Either you are not on Windows, or there is a
problem with the dogadjajC library!" );
return;
}

Dogadjajava dogadjaj = new Dogadjajava();
listener = new DogadjajavaTest();
dogadjaj.addDogadjajavaListener( listener );
dogadjaj.show();

// Instructions
System.err.println( "See the mouse? Click it!" );

// Wait for the bitter end
try
{
synchronized( listener )
{
listener.wait();
}
}
catch( InterruptedException x )
{
}

// Time to die
dogadjaj.removeDogadjajavaListener( listener );
dogadjaj.hide();

System.err.println( "Goodbye!" );
}

public void onDogadjajClicked( Dogadjajava source )
{
synchronized( listener )
{
listener.notifyAll();
}
System.out.println("Klik misem!\n");
}
}

/***************************************dogadjajC.cpp****************************************/
#include "stdafx.h"
#include "Dogadjajava.h"
#include "DogadjajCHandler.h"

HINSTANCE g_instance = NULL;


BOOL WINAPI DllMain
(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
switch( fdwReason )
{
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:

case DLL_PROCESS_ATTACH:
g_instance = hinstDLL;
break;
}
return TRUE;
}


extern "C"
/*
* Class: Dogadjajava
* Method: nativeDisable
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeDisable
(JNIEnv *env, jobject object)
{
/*test*/
printf(" C: nativeDisable\n");

// Get handler
DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object
);

// Disable it
if( l_handler )
l_handler->disable();
}


extern "C"
/*
* Class: Dogadjajava
* Method: nativeEnable
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Dogadjajava_nativeEnable
(JNIEnv *env, jobject object)
{
/*test*/
printf(" C: nativeEnable\n");

// Get handler
DogadjajCHandler *l_handler = DogadjajCHandler::extract( env, object
);

// Create our handler
l_handler = new DogadjajCHandler( env, object );

// Enable it
if( l_handler )
l_handler->enable( env );

}

/****************************************dogadjajCHandler.cpp***************************************/
#include "stdafx.h"
#include "DogadjajCHandler.h"
#include "DogadjajCThread.h"


#define WM_MOUSE_CLICK (WM_USER+1)



DogadjajCHandler *DogadjajCHandler::extract( JNIEnv *env, jobject
object )
{
/*test*/
printf(" C: extract\n");

// Get field ID
jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( object ),
"handler", "I" );

// Get field
DogadjajCHandler *l_handler = (DogadjajCHandler *) env->GetIntField(
object, l_handlerId );

return l_handler;
}


DogadjajCHandler::DogadjajCHandler( JNIEnv *env, jobject object)
{
/*test*/
printf(" C: konstruktor\n");

m_window = NULL;

// Reference object
m_object = env->NewGlobalRef( object );

// Get method ID
m_fireClicked = env->GetMethodID( env->GetObjectClass( m_object ),
"fireClicked", "()V" );

// Get field ID
jfieldID l_handlerId = env->GetFieldID( env->GetObjectClass( m_object
), "handler", "I" );

// Set field
env->SetIntField( m_object, l_handlerId, (jint) this );
}


DogadjajCHandler::~DogadjajCHandler()
{
/*test*/
printf(" C: destruktor\n");

// Get field ID
jfieldID l_handlerId = g_DogadjajCThread.m_env->GetFieldID(
g_DogadjajCThread.m_env->GetObjectClass( m_object ), "handler", "I" );

// Set field
g_DogadjajCThread.m_env->SetIntField( m_object, l_handlerId, 0 );

// Release our reference
g_DogadjajCThread.m_env->DeleteGlobalRef( m_object );

// Destroy window
DestroyWindow( m_window );

}


void DogadjajCHandler::enable( JNIEnv *env )
{
/*test*/
printf(" C: enable\n");

g_DogadjajCThread.MakeSureThreadIsUp( env );
while( !PostThreadMessage( g_DogadjajCThread, WM_CLICK, enableCode,
(LPARAM) this ) )
Sleep( 1000 );
}


void DogadjajCHandler::doEnable()
{
/*test*/
printf(" C: doEnable\n");

// Register window class
WNDCLASSEX l_Class;
l_Class.cbSize = sizeof( l_Class );
l_Class.style = 0;
l_Class.lpszClassName = TEXT( "DogadjajCHandlerClass" );
l_Class.lpfnWndProc = WndProc;
l_Class.hbrBackground = NULL;
l_Class.hCursor = NULL;
l_Class.hIcon = NULL;
l_Class.hIconSm = NULL;
l_Class.lpszMenuName = NULL;
l_Class.cbClsExtra = 0;
l_Class.cbWndExtra = 0;

if( !RegisterClassEx( &l_Class ) )
return;

// Create window
m_window = CreateWindow
(
TEXT( "DogadjajCHandlerClass" ),
TEXT( "DogadjajCHandler" ),
WS_POPUP,
0, 0, 0, 0,
NULL,
NULL,
0,
NULL
);

if( !m_window )
return;

// Set this pointer
SetWindowLong( m_window, GWL_USERDATA, (LONG) this );

}

void DogadjajCHandler::disable()
{
/*test*/
printf(" C: disable\n");

PostThreadMessage( g_DogadjajCThread, WM_CLICK, disableCode, (LPARAM)
this );
}


void DogadjajCHandler::fireClicked()
{
/*test*/
printf("C: DogadjajCHandler-disable\n");

g_DogadjajCThread.m_env->CallVoidMethod( m_object, m_fireClicked );
}


LRESULT CALLBACK DogadjajCHandler::WndProc( HWND hWnd, UINT uMessage,
WPARAM wParam, LPARAM lParam )
{
/*test*/
printf(" C: WndProc\n");

// Check for our special notification message
if( ( uMessage == WM_MOUSE_CLICK ) && ( INT(lParam) == WM_LBUTTONDOWN
) )
{
DogadjajCHandler *l_this = (DogadjajCHandler *) GetWindowLong( hWnd,
GWL_USERDATA );

// Click!
l_this->fireClicked();

return 0;
}
else
return DefWindowProc( hWnd, uMessage, wParam, lParam );
}

/*****************************************dogadjajCThread.cpp*************************************/
#include "stdafx.h"
#include "DogadjajCThread.h"
#include "DogadjajCHandler.h"


DogadjajCThread g_DogadjajCThread;


DogadjajCThread::DogadjajCThread()
{
/*test*/
printf(" C: DogadjajCThread-konstruktor\n");

m_env = NULL;
m_thread = 0;
m_vm = NULL;
m_handlerCount = 0;
}


void DogadjajCThread::MakeSureThreadIsUp( JNIEnv *env )
{
/*test*/
printf(" C: MakeSureThreadIsUp\n");

if( !m_thread )
{
// Get VM
env->GetJavaVM( &m_vm );

// Start "native" thread
CreateThread
(
NULL,
0,
ThreadProc,
this,
0,
&m_thread
);
}
}


DogadjajCThread::eek:perator DWORD ()
{
return m_thread;
}


DWORD WINAPI DogadjajCThread::ThreadProc( LPVOID lpParameter )
{
/*test*/
printf(" C: Threadproc\n");

DogadjajCThread *l_this = (DogadjajCThread *) lpParameter;

// Attach the thread to the VM
l_this->m_vm->AttachCurrentThread( (void**) &l_this->m_env, NULL );

MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
if( msg.message == WM_CLICK )
{
// Extract handler
DogadjajCHandler *l_handler = (DogadjajCHandler*) msg.lParam;

switch( msg.wParam )
{
case DogadjajCHandler::enableCode:

l_this->m_handlerCount++;
l_handler->doEnable();
break;

case DogadjajCHandler::disableCode:

// Destroy it!
delete l_handler;

// No more handlers?
if( !--l_this->m_handlerCount )
{
l_this->m_thread = 0;

// Detach thread from VM
l_this->m_vm->DetachCurrentThread();

// Time to die
ExitThread( 0 );
}
break;
}
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}

// Detach thread from VM
l_this->m_vm->DetachCurrentThread();

return 0;
}

I compile all the files as well, but when I run Dogadjajavatest I am
getting
See the mouse> Click it!
line and no reaction. So I have to terminate my program. Does anyone
have any idea what is going on and why this is happening?
Thanks!
 
G

Gordon Beaton

Hi all, I've already been here with similar topic but I need your
help again. I wrote the code that should be catch an event like
"left button of mouse clicked", using java JNI and C. I wrote it by
following the Desktop Indicator sample I've found on Internet. here
is the code:

You are truly an optimist if you expect someone to read through the
530 lines of code (that you "found on Internet") to find an error
you've only described as "doesn't work".

I suggest you return to the place you found it and ask the author. Or
reduce the problem significantly and provide a better description of
what happens, and what you've done to try to analyze the problem.

/gordon
 
G

ginjasvinja

I am not an optimist I am desperate.The code from Internet is much
longer and working fine. My code does not work as well. I and I
expected that someone will recognize the problem he/she had and give
some advice.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top