TCITEM (user32)
Last changed: -194.138.39.54

.
Summary
Specifies or receives the attributes of a tab item.

C# Signature:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
    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:

None.

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

None.

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);

Marshal.FreeHGlobal(TextPtr);

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);

Marshal.FreeHGlobal(ptr);

int res = SendMessage(handle, TCM_GETITEMA, index, tcitemPtr);

ptr = Marshal.AllocHGlobal(512);

ReadProcessMemory(process, pszTextPtr, ptr, 512, out bytesReaded);

L_buf = Marshal.PtrToStringAnsi(ptr);

Marshal.FreeHGlobal(ptr);

ptr = Marshal.AllocHGlobal(Marshal.SizeOf(tcitem));

ReadProcessMemory(process, tcitemPtr, ptr, (int)Marshal.SizeOf(tcitem), out bytesReaded);

tcitem = (TCITEM)Marshal.PtrToStructure(ptr, tcitem.GetType());

Marshal.FreeHGlobal(ptr);

VirtualFreeEx(process, tcitemPtr, 0, FreeType.Release);

VirtualFreeEx(process, pszTextPtr, 0, FreeType.Release);

#endregion

#region defines

Flags

public enum FreeType

{

    Decommit = 0x4000,
    Release = 0x8000,

}

Flags

enum ProcessAccessFlags : uint

{

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

}

Flags

public enum AllocationType

{

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

}

Flags

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);

[DllImport("kernel32.dll")]

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);

#endregion

You can find some more ideas here: http://www.andreas-reiff.de/2011/06/c-speicher-anderen-prozess-befullen-lassen-checken-ob-ein-button-gedruckt/ (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).

Documentation
TCITEM on MSDN