Intercepting messages inside Is­Dialog­Message, installing the message filter

Windows devs go feral as the Escape key gets a trap door

TLDR: Raymond Chen shows how to catch the Escape key in Windows dialogs before it triggers Cancel, using a message filter and a custom signal. Comments erupt into old-school vs modern UI wars, with UX purists clashing against enterprise pragmatists worried about data loss and nested dialog chaos.

Windows legend Raymond Chen just dropped a nerdy mic: how to catch the Escape key inside a Windows dialog using a message filter, so it doesn’t instantly turn into “Cancel.” Translation: your app can say “wait!” before the window slams shut. The community? Utterly split. The old‑school crew cheered, calling it “classic Win32 craftsmanship,” while modern app folks rolled their eyes: “Why are we still doing this in 2026? Use a modern UI.” Acronym cheat sheet: ESC is the Escape key; IDCANCEL is the default “Cancel” action; MSGF_DIALOGBOX means “dialog filter”; and a custom signal called DM_ESC_PRESSED lets the dialog decide. Cue drama over “global variables” and “thread_local” (a per‑thread storage trick): skeptics warned it’s brittle, fans said it’s pragmatic. One juicy real‑world twist—nested dialogs like “View certificate” spawning “View parent certificate”—had commenters yelling “dialog Inception!” and posting memes of buttons canceling buttons. UX purists argued, “If you need to intercept ESC, your design is wrong,” countered by enterprise vets: “Preventing data loss beats purity.” The funniest take: “Intercepting ESC is like catching your ex before they ghost.” Chen teased more fixes next time, and the crowd popped popcorn. Read the deep dive at Old New Thing

Key Points

  • IsDialogMessage calls CallMsgFilter with MSGF_DIALOGBOX before processing messages, enabling interception.
  • A hook procedure can detect ESC destined for the dialog and send a DM_ESC_PRESSED message to the dialog.
  • The dialog procedure returns TRUE to block default processing or FALSE to allow it, enabling custom ESC handling.
  • The message hook is installed before creating the dialog and removed when the dialog is dismissed.
  • Using a global variable for the dialog handle limits multi-threaded use; thread_local helps but nested dialogs on the same thread remain problematic.

Hottest takes

“If you’re trapping ESC, your UX is already the bug” — pixelPriest
“Message hooks are 1995 energy—and I love it” — regeditRanger
“Thread‑local: great until you date two dialogs on one thread” — callback_cowboy
Made with <3 by @siedrix and @shesho from CDMX. Powered by Forge&Hive.