tags:

views:

1336

answers:

2

Using Winspector I've found out the ID of the child textbox I want to change is 114. Why isn't this code changing the text of the TextBox?

    [DllImport("user32.dll")]
    static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int msg, int Param, string s);

    const int WM_SETTEXT = 0x000c;

    private void SetTextt(IntPtr hWnd, string text)
    {
        IntPtr boxHwnd = GetDlgItem(hWnd, 114);
        SendMessage(boxHwnd, WM_SETTEXT, 0, text);
    }
+1  A: 

The following is what I've used successfully for that purpose w/ my GetLastError error checking removed/disabled:

[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
public const uint WM_SETTEXT = 0x000C;

private void InteropSetText(IntPtr iptrHWndDialog, int iControlID, string strTextToSet)
{
    IntPtr iptrHWndControl = GetDlgItem(iptrHWndDialog, iControlID);
    HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
    SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, strTextToSet);
}

I've tested this code and it works, so if it fails for you, you need to be sure that you are using the right window handle (the handle of the Dialog box itself) and the right control ID. Also try something simple like editing the Find dialog in Notepad.

I can't comment yet in the post regarding using (char *) but it's not necessary. See the second C# overload in p/Invoke SendMessage. You can pass String or StringBuilder directly into SendMessage.

I additionally note that you say that your control ID is 114. Are you certain WinSpector gave you that value in base 10? Because you are feeding it to GetDlgItem as a base 10 number. I use Spy++ for this and it returns control IDs in base 16. In that case you would use:

IntPtr boxHwnd = GetDlgItem(hWnd, 0x0114);
Greg
WinSpector returns base 10 numbers. I've made a little test application with Visual Studio and this technique works fine, but it doesn't work for real application I'm working with.
Kirschstein
When you step through the code w/ the real application, does GetDlgItem() return a non-zero value?
Greg
Yes, it does, and I can grab existing text from it using WM_GETTEXT. It's just WM_SETTEXT that isn't working.
Kirschstein
Sorry if I'm suggesting obvious things, but sometimes it's good to just talk these things out. I think the next thing I would try would be to alter something like the title bar text of the main window (if it has one), and see if I can change that - in other words, change the window text of a window that is most likely not being modified by the program. If that works, then try some text of a static control, like a label, in the window. If both of those work, it would indicate to me that the program is handling that textbox in an unusual manner. continued...
Greg
I would also try watching the textbox control w/ Spy++ (or whatever tool you prefer) to see what messages it is receiving. You should be able to verify that the textbox is receiving your WM_SETTEXT and if the program is sending something that may be overriding your actions.
Greg
The textbox is never receiving a WM_SETTEXT message, it receives something else, I can't remember off the top of my head what this is, but it's on a char by char basis. What I've decided to do instead (because I just want this thing _working_) is to click over the input box and send a series of keybd_events with the desired string in. Cheers for your help Greg, although it doesn't answer my specific problem, it works in general, so I'm marking it as the answer.
Kirschstein
Thanks, Kirschstein. Good luck with your workaround.
Greg
A: 

Are you sure you are passing text right? SendMessage last param should be a pointer to char* containing text you want to set.
Look at my "crude hack" of setting text in http://stackoverflow.com/questions/828935/how-to-get-selected-cells-from-tdbgrid-in-delphi-5/833736#833736
this is done in Delphi 5, where PChar is char* alias, and I simply cast it as int (Integer in Delphi).

smok1