TCITEM (user32)
Last changed: -

Specifies or receives the attributes of a tab item.

C# Signature:

    struct TCITEM
        public uint mask;
        public int state;
        public int statemask;
        public IntPtr text;
        public int size;
        public int image;
        public int param;

VB Signature:

Declare Function TCITEM Lib "user32.dll" (TODO) As TODO

User-Defined Types:


Alternative Managed API:

Do you know one? Please contribute it!



Tips & Tricks:

Please add some!

Sample Code:

I slightly edited some things, so maybe it doesn't work out of the box, should be 99% fine though.


    #region code
    TCITEM tcitem = new TCITEM();
    tcitem.size = 200;
    uint ProcessID;
    GetWindowThreadProcessId((IntPtr)handle, out ProcessID);
    IntPtr process = OpenProcess(ProcessAccessFlags.VMOperation | ProcessAccessFlags.VMRead |
    ProcessAccessFlags.VMWrite | ProcessAccessFlags.QueryInformation, false, ProcessID);

    IntPtr pszTextPtr = VirtualAllocEx(process, IntPtr.Zero, 512, AllocationType.Commit, MemoryProtection.ReadWrite);
    IntPtr tcitemPtr = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(TCITEM)), AllocationType.Commit, MemoryProtection.ReadWrite);

    const int TCIF_STATE = 0x10;
    const int TCIF_TEXT = 0x1;
    tcitem.mask = TCIF_STATE | TCIF_TEXT;

    tcitem.text = pszTextPtr;
    string L_buf = "nasenmann ";
    IntPtr TextPtr = Marshal.StringToHGlobalAnsi(L_buf);
    L_buf = "├╝berschrieben";
    int bytesReaded;
    WriteProcessMemory(process, pszTextPtr, TextPtr, 512, IntPtr.Zero);
    IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(tcitem));
    Marshal.StructureToPtr(tcitem, ptr, true);
    tcitem.size = 1; // ├╝berschrieben
    WriteProcessMemory(process, tcitemPtr, ptr, Marshal.SizeOf(tcitem), IntPtr.Zero);
    int res = SendMessage(handle, TCM_GETITEMA, index, tcitemPtr);
    ptr = Marshal.AllocHGlobal(512);
    ReadProcessMemory(process, pszTextPtr, ptr, 512, out bytesReaded);
    L_buf = Marshal.PtrToStringAnsi(ptr);
    ptr = Marshal.AllocHGlobal(Marshal.SizeOf(tcitem));
    ReadProcessMemory(process, tcitemPtr, ptr, (int)Marshal.SizeOf(tcitem), out bytesReaded);
    tcitem = (TCITEM)Marshal.PtrToStructure(ptr, tcitem.GetType());
    VirtualFreeEx(process, tcitemPtr, 0, FreeType.Release);
    VirtualFreeEx(process, pszTextPtr, 0, FreeType.Release);


    #region defines
    public enum FreeType
    Decommit = 0x4000,
    Release = 0x8000,

    enum ProcessAccessFlags : uint
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VMOperation = 0x00000008,
    VMRead = 0x00000010,
    VMWrite = 0x00000020,
    DupHandle = 0x00000040,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    Synchronize = 0x00100000

    public enum AllocationType
    Commit = 0x1000,
    Reserve = 0x2000,
    Decommit = 0x4000,
    Release = 0x8000,
    Reset = 0x80000,
    Physical = 0x400000,
    TopDown = 0x100000,
    WriteWatch = 0x200000,
    LargePages = 0x20000000

    public enum MemoryProtection
    Execute = 0x10,
    ExecuteRead = 0x20,
    ExecuteReadWrite = 0x40,
    ExecuteWriteCopy = 0x80,
    NoAccess = 0x01,
    ReadOnly = 0x02,
    ReadWrite = 0x04,
    WriteCopy = 0x08,
    GuardModifierflag = 0x100,
    NoCacheModifierflag = 0x200,
    WriteCombineModifierflag = 0x400

    [DllImport("user32.dll", SetLastError = true)]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
       uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
    static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
       int dwSize, FreeType dwFreeType);
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool ReadProcessMemory(
     IntPtr hProcess,
     IntPtr lpBaseAddress,
    IntPtr lpBuffer,
     int dwSize,
     out int lpNumberOfBytesRead
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);


You can find some more ideas here: (though it is in German)

I am also working on a generic method to pass structs. It is working for an arbitrary number of strings contained in the struct and is very user friendly. Once it is finished I will post it somewhere on the net as well.

Also, you can use the code here for any situation where you have a struct that contains a pointer to some other structure that you then again need to fill (and read).