How to send a string via PostMessage?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
With the Win32 API, PostMessage is asynchronous: it places a message in another thread's queue and returns immediately. That makes it a poor mechanism for sending an arbitrary string payload directly, because any pointer you pass may become invalid before the receiving window processes the message. For string data, the correct answer is usually SendMessage with WM_COPYDATA, not PostMessage.
Why raw string pointers are unsafe with PostMessage
PostMessage lets you send WPARAM and LPARAM, but those are just integer-sized values. If you cast a pointer to a string buffer into LPARAM and then return, the receiver may later read freed or modified memory.
That is the key issue: PostMessage does not synchronize lifetime.
Use WM_COPYDATA with SendMessage for cross-process strings
WM_COPYDATA is the standard Win32 way to send a block of data, including a string, to another window synchronously.
Receiver side:
Because SendMessage is synchronous, the sender keeps the buffer alive for the duration of the call.
Use PostMessage only for lightweight identifiers or notifications
PostMessage is still useful when the message content is small and self-contained, such as an integer command code, an index, or a signal that tells the receiver to fetch data from a shared place.
In that design, the message does not carry the string itself. It carries a small token the receiver knows how to interpret safely.
Shared memory is possible, but more complex
If you truly need asynchronous cross-process transfer with larger payloads, use shared memory or another IPC mechanism. The message can then notify the receiver that data is ready in a known shared region.
That architecture is more work because it requires synchronization, ownership rules, cleanup, and security review. For ordinary window-to-window text transfer, WM_COPYDATA is simpler.
Same-process scenarios still need lifetime discipline
Even inside one process, a posted pointer can be dangerous if the originating stack frame or heap allocation goes away before the message is handled. The process boundary is not the real issue. The asynchronous queue is.
That is why code that "works on my machine" with PostMessage and a string pointer is still unsafe.
Consider higher-level IPC if text exchange is central
If your application frequently exchanges strings between components, window messages may be the wrong abstraction. Named pipes, sockets, COM, or framework-level messaging systems are often easier to maintain than a custom message protocol built on raw pointers.
Common Pitfalls
- Passing a pointer to a temporary or stack-allocated string through
PostMessage. - Assuming same-process communication makes posted string pointers safe.
- Using
PostMessagewhen the real need is synchronous payload transfer. - Forgetting that
WPARAMandLPARAMdo not manage ownership or lifetime. - Rebuilding a fragile custom shared-memory protocol when
WM_COPYDATAwould solve the immediate problem.
Summary
- Do not send raw string pointers through
PostMessageunless lifetime is guaranteed by another mechanism. - Use
SendMessagewithWM_COPYDATAfor normal Win32 string transfer. - Use
PostMessagefor small codes or notifications, not arbitrary text payloads. - Treat asynchronous messaging as a lifetime problem first, not a casting problem.
- Consider higher-level IPC if string exchange is a core part of the design.

