Pergunta

Eu estou tentando chamar SendMessage com um parâmetro uint de Java, mas eu não pode converter int para uint. Eu não posso mudar o parâmetro uint em SendMessage porque é uma função do Windows. Existe alguma maneira de fazer isso?

Fundo: Na verdade, estou usando Processing, e eu estou seguindo os seguintes tutoriais para acesso user32.dll: http: / /processing.org/hacks/hacks:jnative

http://jnative.free. fr / SPIP-v1-8-3 / article.php3? id_article = 8

E eu estou seguindo este para chamar SendMessage http://www.codeproject.com/KB/cs/Monitor_management_guide.aspx

Aqui está o meu código, GetActiveWindow fina funciona, é a partir do segundo link acima.

 int SC_MONITORPOWER = 0xF170;
 int WM_SYSCOMMAND = 0x0112;
 int MONITOR_ON = -1;
 int MONITOR_OFF = 2;
 int MONITOR_STANDBY = 1;

HWND ValidHWND = org.xvolks.jnative.util.User32.GetActiveWindow(); 
org.xvolks.jnative.util.User32.SendMessage(ValidHWND, (UINT)WM_SYSCOMMAND, 
          (WPARAM)SC_MONITORPOWER, (LPARAM)MONITOR_STANDBY);

última linha é onde o erro acontece, ele diz que o UINT esperado no tipo User32 não é aplicável ao tempo eu fornecido. Não posso modificar SendMessage quer

Aqui está o arquivo java correspondente a chamada acima invoca, a parte GetActiveWindow funciona bem, já que é a partir de um tutorial. Estou tentando adaptar SendMessage para segui-lo, mas eu não percebi isso tudo ainda. No entanto, eu não acho que é importante para o erro que estou recebendo, desde alterando os parâmetros para SendMessage aqui não muda o que os espera compilador. Eu tentei mudar int Msg para uint Msg ao longo Msg, o compilador ainda espera uint a partir do código acima.

public class Paul_s_User32 extends User32 {
public HANDLE GetActiveWindow() {
    JNative GetActiveWindow = new JNative(DLL_NAME, "GetActiveWindow");
    GetActiveWindow.setRetVal(Type.INT);
    GetActiveWindow.invoke();
    HWND handle = new HWND(GetActiveWindow.getRetValAsInt());
    GetActiveWindow.dispose();
    return handle;
}
public IntPtr SendMessage(IntPtr hWnd, int Msg, 
          IntPtr wParam, IntPtr lParam) {
    JNative SendMessage = new JNative(DLL_NAME, "SendMessage");
    //SendMessage.setRetVal(Type.long);
    SendMessage.invoke();

    SendMessage(ValidHWND, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_STANDBY);
}
Foi útil?

Solução

Se você estiver usando o pacote org.xvolks.jnative, todos os parâmetros (HWND, uint wParam e lParam) são classes em org.xvolks.jnative.misc.basicStructures. Então você deve ser capaz de fazer algo assim (código não testado):

import org.xvolks.jnative.misc.basicStructures.*;
...

User32.SendMessage(
    new HWND(ValidHWND),
    new UINT(WM_SYSCOMMAND), 
    new WPARAM(SC_MONITORPOWER),
    new LPARAM(MONITOR_STANDBY);

Para sua referência, aqui é a implementação de SendMessage em org.xvolks.jnative.util.User32. Como você pode ver, o código jnative não se importa em tudo sobre assinados e não assinados. Você pode achar que é útil para agarrar a jnative código fonte .

public static LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) throws NativeException, IllegalAccessException
{
    JNative SendMessage = new JNative(DLL_NAME, "SendMessageA");
    SendMessage.setRetVal(Type.INT);
    int pos = 0;
    SendMessage.setParameter(pos++, hWnd.getValue());
    SendMessage.setParameter(pos++, Msg.getValue());
    SendMessage.setParameter(pos++, wParam.getValue());
    SendMessage.setParameter(pos++, lParam.getValue());
    SendMessage.invoke();
    pos = SendMessage.getRetValAsInt();
    SendMessage.dispose();
    return new LRESULT(pos);
}

E se você decidir que não gosta JNative, você poderia dar uma olhada Java Native Access ( JNA) .

Outras dicas

Do ponto de vista de dados, um uint e um int são a mesma coisa - um valor de 32 bits. A única diferença é a forma como opcodes interpretar o bit superior. Ao passar entre Java e C, você está só de passagem 32 bits, assim que o sinal não é relevante. A solução é simplesmente declarar o parâmetro uint como um int.

BTW, a questão da não assinado / assinado não é significativo aqui porque o valor uMsg para SendMessage é positivo para todas as mensagens da Microsoft, e para essa matéria, é mais do que provável positivo para qualquer outra coisa que é provável que encontro.

Como o Java não tem a noção de tipos não assinados, você tem que usar um longo para representar um int não assinado. Verifique neste site para exemplos de como fazer isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top