Implementar função WndProc (C++) usando JNA

Olá pessoal!

Tenho um microterminal que vem junto com uma DLL pra comunicação entre o sistema e o microterminal.
Eu estou usando JNA para isso, e estou tendo alguns progressos.

A documentação do equipamento exige que eu implemente a função WndProc pra implementar os “CallBack” do equipamento, ou seja, implementando esta função eu consigo capturar os eventos do teclado do microterminal.

Segue abaixo como que eu fiz pra implementar essa função usando Java e JNA:

[code]import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;

public interface MyUser32 extends User32 {

public static final MyUser32 USER32_INSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS);

public static final int GWLP_WNDPROC = -4;

public int SetWindowLong(WinDef.HWND hWnd, int nIndex, Callback callback);

}
[/code]

[code]import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;

public interface MyListener extends StdCallCallback {

public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);

}[/code]

E na classe da tela eu faço isso, logo após a tela ficar visível:

[code]
MyListener listener = new MyListener() {

@Override
public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam) {
	//faz algo aqui
	return new LRESULT(0);
}

};

HWND hWnd = new HWND();
hWnd.setPointer(Native.getWindowPointer(MicroTerm.this));
MyUser32.USER32_INSTANCE.SetWindowLong(hWnd, MyUser32.GWLP_WNDPROC, listener);[/code]

Bom, agora o problema:
Apesar do programa se comunicar com o microterminal e capturar os eventos perfeitamente, a minha tela fica travada e eu não consigo fechar o programa no botão fechar.
Se eu comento essa linha: hWnd.setPointer(Native.getWindowPointer(MicroTerm.this));, o meu programa para de travar e tambem para de escutar os eventos do microterminal.

Já tentei colocar essa parte do “callback” em uma outra Thread, mas continuou igual.
Alguem consegue saber o que eu estou fazendo de errado?

Obrigada a todos

Você não chamou DefaultWindowProc dentro do tratamento de WndProc.

Se você não fizer isso, você estará afirmando ao Windows que todos os tratamentos das mensagens direcionadas para essa janela serão feitas pelo seu método WindowProc. Isso quer dizer que sua janela ficará congelada porque nenhuma mensagem será tratada, exceto as que você tratar explicitamente.

http://msdn.microsoft.com/pt-br/library/ms633570.aspx#designing_proc

Olá, bezier curve!!

Obrigada pela resposta!
Fiz o que vc me disse, e minhas classes ficaram assim:

[code]package br.com.tdta.service.microterm;

import com.sun.jna.Callback;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.win32.W32APIOptions;

public interface MyUser32 extends User32 {

public static final MyUser32 USER32_INSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS);

public int SetWindowLong(WinDef.HWND hWnd, int nIndex, Callback callback);

public LRESULT DefWindowProc(WinDef.HWND hwnd, int uMsg, WinDef.WPARAM wParam, WinDef.LPARAM lParam);

}
[/code]

public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam) { switch (uMsg) { case RECEIVE_DATA: //faz algo return new LRESULT(0); case CONNECT: //faz algo return new LRESULT(0); default: return Win32.USER32_INSTANCE.DefWindowProc(hWnd, uMsg, uParam, lParam); } }

e, na chamada do método SetWindowLong, estou fazendo assim:

MyUser32.USER32_INSTANCE.SetWindowLong(hWnd, StdCallLibrary.STDCALL_CONVENTION, listener); //troquei MyUser32.GWLP_WNDPROC por StdCallLibrary.STDCALL_CONVENTION

Obrigada pela ajuda!
Funcionou certinho aqui!

[quote=eliangela]e, na chamada do método SetWindowLong, estou fazendo assim:

MyUser32.USER32_INSTANCE.SetWindowLong(hWnd, StdCallLibrary.STDCALL_CONVENTION, listener); //troquei MyUser32.GWLP_WNDPROC por StdCallLibrary.STDCALL_CONVENTION

Olá, pessoal!

Este tópico ainda não está resolvido :oops:
a alteração que eu fiz não funcionou direito, e minha janela continua estranha.

Se eu fizer isso:

MyUser32.USER32_INSTANCE.SetWindowLong(hWnd, StdCallLibrary.STDCALL_CONVENTION, listener);

A janela funciona certinho, finalizando todas as DLLs, etc, mas a comunicação não funciona!

Se eu fizer assim:

MyUser32.USER32_INSTANCE.SetWindowLong(hWnd, MyUser32.GWL_WNDPROC, listener);

A comunicação funciona, mas a janela não funciona direito, como se tivesse “meio” travada. Quando eu fecho a janela, ela fica invisível, mas não fecha o programa.
Os botões tbem não estão “clicando”.

Eu testei esse parâmetro com todas constantes possíveis, como mostra no site: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633591%28v=vs.85%29.aspx.
O que mais falta fazer?

Obrigada