This Question is Answered

1 "correct" answer available (4 pts) 1 "helpful" answer available (2 pts)
4 Replies Last post: Jan 29, 2008 12:05 AM by Don  
Don   13 posts since
Jan 12, 2008
Currently Being Moderated

Jan 23, 2008 9:03 AM

help using the sendMessageEx method in Wnd class?

Firstly I'll start with a high level description of my problem. What I would like to do is to manipulate "Edit" controls in native windows applications by getting and setting their text items. The two ways I can see of doing this are:

 

(a)

 

Calling:

GetDlgItemText http://msdn2.microsoft.com/en-us/library/ms645489(VS.85).aspx

SetDlgItemText http://msdn2.microsoft.com/en-us/library/ms645521(VS.85).aspx

 

from user32.dll

 

Tried this but I couldn't wrap my head around all the parameter conversions. Even after following these mappings:

 

http://www.teamdev.com/winpack/windowsTypes.jsf

 

I couldn't get or set the text

 

(b)

 

The simplest method seems to be to call sendMessageEx in the Wnd class. I would like to send it a WM_SETTEXT message but the parameters seem too restrictive. It takes int msg, long wParam, long lParam. If you have a look at the WM_SETTEXT message in MSDN

 

http://msdn2.microsoft.com/en-us/library/ms632644(VS.85).aspx

 

You are supposed to feed it the string via lparam...but how can you do this if it only takes int/long as a parameter. Similarly for the WM_GETTEXT message how do you get back the String as a return type?

Serge Piletsky TeamDev Ltd. 670 posts since
Apr 24, 2006
Currently Being Moderated
1. Jan 23, 2008 3:44 PM in response to: Don
Re: help using the sendMessageEx method in Wnd class?

Hi Don,

 

Yes, the existing Wnd.sendMessageEx() method is not quite convenient, because it expects LPARAM and WPARAM arguments as Java long values. But it's quite possible to send string values using even the current implementation and the following example demonstrates this technique:

    Str string = new Str("String value");
    Pointer stringPtr = new Pointer(string);
 
    Pointer.Void stringHandle = new Pointer.Void();
    stringPtr.castTo(stringHandle);
 
    long lParam = stringHandle.getValue();
    wnd.sendMessageEx(Msg.WM_SETTEXT, 0, lParam);

 

I undertand that such pointers cast is not obvious enough therefore I have created the following example, which contains the wrappers for SetDlgItemText/GetDlgItemText API functions as well:

 

import com.jniwrapper.*;
import com.jniwrapper.win32.FunctionName;
import com.jniwrapper.win32.IntPtr;
import com.jniwrapper.win32.Msg;
import com.jniwrapper.win32.process.Process;
import com.jniwrapper.win32.ui.User32;
import com.jniwrapper.win32.ui.Wnd;
 
/**
 * This example demonstrates how to wrap SetDlgItemText, GetDlgItemText and SendMessage API functions.
 *
 * @author Serge Piletsky
 */
public class Sample {
 
    public static final FunctionName FUNCTION_SetDlgItemText = new FunctionName("SetDlgItemText");
    public static final FunctionName FUNCTION_GetDlgItemText = new FunctionName("GetDlgItemText");
 
    public static final FunctionName FUNCTION_SendMessage = new FunctionName("SendMessage");
 
    /**
     * Sends a message to the specified window.
     *
     * @param wnd    window handle
     * @param msg    message
     * @param wParam WPARAM
     * @param lParam LPARAM
     * @return the return value meaning depends on the message.
     */
    public static long sendMessage(Wnd wnd, int msg, Parameter wParam, Parameter lParam) {
        Function sendMessage = User32.getInstance().getFunction(FUNCTION_SendMessage.toString());
        IntPtr result = new IntPtr();
        sendMessage.invoke(result,
                wnd,
                new UInt(msg),
                wParam != null ? wParam : new IntPtr(),
                lParam != null ? lParam : new IntPtr());
        return result.getValue();
    }
 
    /**
     * Sets the title or text of a control in a dialog box.
     *
     * @param wnd       Handle to the dialog box that contains the control
     * @param idDlgItem Specifies the control with a title or text to be set
     * @param string    String that contains the text to be copied to the control
     * @return If the function succeeds, the return value is true
     */
    public static boolean setDlgItemText(Wnd wnd, int idDlgItem, String string) {
        Function sendMessage = User32.getInstance().getFunction(FUNCTION_SetDlgItemText.toString());
        Bool result = new Bool();
        sendMessage.invoke(result,
                wnd,
                new Int(idDlgItem),
                new Pointer(new Str(string)));
        return result.getValue();
    }
 
    /**
     * Returns the title or text associated with a control in a dialog box.
     *
     * @param wnd       Handle to the dialog box that contains the control
     * @param idDlgItem Specifies the control with a title or text to be set
     * @return return value is true
     */
    public static String getDlgItemText(Wnd wnd, int idDlgItem) {
        Function sendMessage = User32.getInstance().getFunction(FUNCTION_GetDlgItemText.toString());
        final int maxCount = 512;
        Bool result = new Bool();
        Str resultString = new Str(maxCount);
        sendMessage.invoke(result,
                wnd,
                new Int(idDlgItem),
                new Pointer(resultString),
                new Int(maxCount));
        return resultString.getValue();
    }
 
    public static void main(String[] args) throws Exception {
        // start Notepad application and wait 2 seconds
        Process notepadProcess = new Process("notepad");
        Thread.sleep(2000);
 
        // find Notepad window
        Wnd notepadWindow = Wnd.findWindowByName("Untitled - Notepad");
 
        // send WM_SETTEXT message to change the caption of Notepad window
        sendMessage(notepadWindow, Msg.WM_SETTEXT, null, new Pointer(new Str("Hello, World!")));
        Thread.sleep(2000);
 
        // send WM_CLOSE message to close the Notepad window
        sendMessage(notepadWindow, Msg.WM_CLOSE, null, null);
 
        notepadProcess.waitFor();
        System.out.println("Done.");
    }
}

 

Also, we will add these functions to Wnd class in the next version of WinPack.

 

-Serge

Serge Piletsky TeamDev Ltd. 670 posts since
Apr 24, 2006
Currently Being Moderated
3. Jan 24, 2008 8:44 PM in response to: Don
Re: help using the sendMessageEx method in Wnd class?

Hi,

 

Here are examples that demonstrate how to get the resulting string value after invocation of sendMessage method with WM_GETTEXT message:

 

        int maxNumberOfChars = 512;
        Str result = new Str(maxNumberOfChars);
 
        sendMessage(notepadWindow, Msg.WM_GETTEXT, new Int(maxNumberOfChars), new Pointer(result));
 
        System.out.println("result = " + result);

 

Or

 

        int maxNumberOfChars = 512;
        Str result = new Str(maxNumberOfChars);
        Pointer resultPtr = new Pointer(result);
        Pointer.Void resultHandle = new Pointer.Void();
        resultPtr.castTo(resultHandle);
 
        notepadWindow.sendMessageEx(Msg.WM_GETTEXT, maxNumberOfChars, resultHandle.getValue());
 
        System.out.println("result = " + result);

 

-Serge

More Like This

  • Retrieving data ...