Home‎ > ‎Windows programming‎ > ‎

Manipulating windows in other processes

This topic is very broad, from setwindowshookex to how to properly use wm_get messages, or difference between postmessage & sendmessage.
Below are some code examples that can be useful in general.


Button wrapper class written in C#

class ButtonWrapper
{
    IntPtr _parentHwnd;
    IntPtr _hwnd;
    public ButtonWrapper(IntPtr hwnd)
    {
        _hwnd = hwnd;
        _parentHwnd = Win32.GetParent(hwnd);

        if (_parentHwnd == null)
        {
            throw new Exception("parent window not found");
        }

        StringBuilder className = new StringBuilder(1024);
        //Get the window class name
        Win32.GetClassName(hwnd, className, className.Capacity);
        Debug.Assert(className.ToString() == "Button");

        if (className.ToString() != "Button")
        {
            throw new Exception("hwnd does not point to a button");
        }
    }

    public void Click()
    {
            
        int wParam = Win32.MakeLong(Win32.GetWindowLong(_hwnd, Win32.GWL_ID), Win32.BM_CLICK);
        int lParam = _hwnd.ToInt32();
        int ret = Win32.SendMessage(_parentHwnd, (int)Win32.Messages.WM_COMMAND, new IntPtr(wParam), new IntPtr(lParam)).ToInt32();
    }

    public string GetText()
    {
        int length = Win32.GetWindowTextLength(_hwnd);
        StringBuilder text = new StringBuilder(length + 1);
        Win32.GetWindowText(_hwnd, text, text.Capacity);
        return text.ToString();
    }
}

ListViewWrapper class written in C#

// useful msdn link: http://msdn.microsoft.com/en-us/library/windows/desktop/ff485961%28v=VS.85%29.aspx (List View Messages )
class ListViewWrapper
{
    IntPtr _hwnd;
    public ListViewWrapper(IntPtr hwnd)
    {
        _hwnd = hwnd;
    }

    public int GetItemCount()
    {
        return Win32.SendMessage(_hwnd, Win32.LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();
    }

    public int GetSelectedItemsCount()
    {
        return Win32.SendMessage(_hwnd, Win32.LVM_GETSELECTEDCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();
    }

    public bool IsItemSelected(int itemIdx)
    {
        return (Win32.LVIS_SELECTED & Win32.SendMessage(_hwnd, Win32.LVM_GETITEMSTATE, new IntPtr(itemIdx), new IntPtr(Win32.LVIS_SELECTED)).ToInt32()) != 0;
    }

    public string GetItemText(int itemIdx)
    {
        // Declare and populate the LVITEM structure
        Win32.LVITEM lvi = new Win32.LVITEM();
        lvi.mask = Win32.LVIF_TEXT;
        lvi.cchTextMax = 512;
        lvi.iItem = itemIdx;  // the zero-based index of the ListView item
        lvi.iSubItem = 0;     // the one-based index of the subitem, or 0 if this
        //  structure refers to an item rather than a subitem
        lvi.pszText = Marshal.AllocHGlobal(512);

        // Send the LVM_GETITEM message to fill the LVITEM structure
        IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
        Marshal.StructureToPtr(lvi, ptrLvi, false);
        int ret = Win32.SendMessage(_hwnd, Win32.LVM_GETITEM, IntPtr.Zero, ptrLvi).ToInt32();

        // Extract the text of the specified item
        string itemText = Marshal.PtrToStringAuto(lvi.pszText);

        Marshal.FreeHGlobal(lvi.pszText);
        Marshal.FreeHGlobal(ptrLvi);

        if (ret == 0)
        {
            throw new Exception("Retrieving the item text has failed");
        }

        return itemText;
    }
    public void UnselectAllItems()
    {
        int itemCnt = GetItemCount();
        for (int idx = 0; idx < itemCnt; ++idx)
        {
            if (IsItemSelected(idx))
            {
                UnselectItem(idx);
            }
        }
    }
    public void UnselectItem(int itemIdx)
    {
        Win32.LVITEM lvi = new Win32.LVITEM();
        lvi.mask = Win32.LVIF_STATE;
        lvi.stateMask = Win32.LVIS_FOCUSED | Win32.LVIS_SELECTED;
        lvi.state = 0;
        lvi.cchTextMax = 0;
        lvi.iImage = 0;

        IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
        Marshal.StructureToPtr(lvi, ptrLvi, false);

        int ret = Win32.SendMessage(_hwnd, Win32.LVM_SETITEMSTATE, new IntPtr(itemIdx), ptrLvi).ToInt32();

        Marshal.FreeHGlobal(ptrLvi);

        if (ret == 0)
        {
            throw new Exception("Unselecting the item has failed");
        }
    }
    // if listview is single select, call UnselectAllItems() before you try to select an item
    public void SelectItem(int itemIdx)
    {
        Win32.LVITEM lvi = new Win32.LVITEM();
        lvi.mask = Win32.LVIF_STATE;
        lvi.stateMask = Win32.LVIS_FOCUSED | Win32.LVIS_SELECTED;
        lvi.state = Win32.LVIS_FOCUSED | Win32.LVIS_SELECTED;
        lvi.cchTextMax = 0;
        lvi.iImage = 0;

        IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
        Marshal.StructureToPtr(lvi, ptrLvi, false);

        int ret = Win32.SendMessage(_hwnd, Win32.LVM_SETITEMSTATE, new IntPtr(itemIdx), ptrLvi).ToInt32();
        Marshal.FreeHGlobal(ptrLvi);

        if (ret == 0)
        {
            throw new Exception("Selecting the item has failed");
        }

    }
}


Comments