Remember the classical model for how processes exit: You cleanly shut down all your worker threads, and then call ExitProcess
. If you don’t follow that model (and given the current programming landscape, you pretty have no choice but to abandon that model, what with DLLs creating worker threads behind your back), it’s even more important that you follow the general guidance of not doing anything scary in your DllMain
function.
Trying to recover from enhancement software that generates fake input incorrectly – The Old New Thing
Posted by jpluimers on 2017/02/08
Be sure to read the details in Trying to recover from enhancement software that generates fake input incorrectly – The Old New Thing [WayBack] (much more Old New Think stuff below):
The most insightful part for me was this diagram listing where various methods enter the message pipeline (I added the GetMessage/PeekMessage
entry):
← GetMessage/PeekMessage
obtains messages hereInbound sent messages ← SendMessage
inserts messages hereInbound posted messages ← PostMessage
inserts messages hereInbound input messages ← SendInput
inserts messages here
The diagram is of course still inaccurate, but gives a good impression on how much lower priority user input has over posted or sent messages.
Similar diagrams for the message loop are from [WayBack] DirectXTutorial.com Lesson 4: The Real-Time Message Loop:
A very high level overview is at [WayBack] Message loop in Microsoft Windows – Wikipedia.
Related:
- [WayBack] GetMessage
- [WayBack] PeekMessage
- [WayBack] TranslateMessage
- [WayBack] DispatchMessage
- [WayBack] SendMessage
- [WayBack] PostMessage
- [WayBack] PostQuitMessage
- [WayBack] SendInput
- [WayBack] SendMessage, PostMessage, and Related Functions – Windows applications | Microsoft Docs
Related Old New Thing posts that were returned by searching for message loop:
- 2003
- Scrollbars:
- 20030723 [WayBack] The scratch program – The Old New Thing
- 20030725 [WayBack] Scrollbars, part 2 – The Old New Thing
- 20030729 [WayBack] Scrollbars, part 3: Optimizing the paint cycle – The Old New Thing
- 20030730 [WayBack] Answer to yesterday’s exercise – The Old New Thing
- 20030731 [WayBack] Scrollbars, part 4: Adding a proportional scrollbar – The Old New Thing
- 20030805 [WayBack] Keyboard accessibility for scrollbars – The Old New Thing
- 20030807 [WayBack] Scrollbars bart 6 – The wheel – The Old New Thing
- 20030811 [WayBack] Scrollbars part 7 – Integrality – The Old New Thing
- 20030813 [WayBack] Scrollbars part 8 – Integral interactive resizing – The Old New Thing
- 20030821 [WayBack] The secret life of GetWindowText – The Old New Thing
- Scrollbars:
- 20030909 [WayBack] Scrollbars part 9 – Maintaining the metaphor – The Old New Thing
- 20030911 [WayBack] Scrollbars part 10 – Towards a deeper understanding of the WM_NCCALCSIZE message – The Old New Thing
- 20030913 [WayBack] Answers to exercises – The Old New Thing
The more precise way of writing the line would have been
rcWindow.bottom += (rcTemp.top - rcWindow.top) - (0 - rcWindow.top);
The first term is the amount of non-client space consumed at the top of the window. The second term is the amount of non-client space consumed at the top of the window, taking wrapping into account. The difference, therefore is the amount by which AdjustWindowRectExneeds to be adjusted. But the two instances of
rcWindow.top
cancel out, leaving justrcTemp.top
. - 20030915 [WayBack] Scrollbars part 11: Towards an even deeper understanding of the WM_NCCALCSIZE message – The Old New Thing
- 20030917 [WayBack] Answers to exercise from Scrollbars Part 11 – The Old New Thing
- 20030930 [WayBack] Why is the readonly property for folders so strange? – The Old New Thing
If a folder has the Readonly or System flag set, then Explorer will look for a
desktop.ini
file which describes the folder customizations. For performance reasons, Explorer does this only if the directory has the +R or +S flag. (This is enormously important on slow networks.) - 20031001 [WayBack] Why do I get spurious WM_MOUSEMOVE messages? – The Old New Thing
- 20031010 [WayBack] Why doesn’t the clock in the taskbar display seconds? – The Old New Thing
The fastest code is code that doesn’t run.
- 20031013 [WayBack] Why is there no WM_MOUSEENTER message? – The Old New Thing
- Scrollbars redux:
- 20031021 [WayBack] Using the TAB key to navigate in non-dialogs – The Old New Thing
- 20031029 [WayBack] Drawing an active-looking caption even when not active – The Old New Thing
- 20031110 [WayBack] Homework assignment about window subclassing – The Old New Thing
- 20031111 [WayBack] Safer subclassing – The Old New Thing
- 20031112 [WayBack] A different type of dialog procedure – The Old New Thing
- 20031113 [WayBack] Another different type of dialog procedure – The Old New Thing
- 20031114 [WayBack] Preventing edit control text from being autoselected in a dialog box – The Old New Thing
- 20031126 [WayBack] Other tricks with WM_GETDLGCODE – The Old New Thing
- 20031202 [WayBack] Which message numbers belong to whom? – The Old New Thing
- 20031223 [WayBack] When programs grovel into undocumented structures… – The Old New Thing
- 20031226 [WayBack] You can read a contract from the other side – The Old New Thing
- Scrollbars:
- 2004
- Calling conventions
- 20040102 [WayBack] The history of calling conventions, part 1 – The Old New Thing
- WayBack: When to use __fastcall
I advise that you never use
__fastcall
unless it is specifically required by the VCL. Using__fastcall
isn’t necessary, it clutters up your code, and it appears to execute a bit slower than the default calling convention.
- WayBack: When to use __fastcall
- 20040105 [WayBack] Why does the x86 have so few registers? – The Old New Thing
- WayBack: An Inside Look at MS-DOS: An Inside Look at MS-DOSThe design decisions behind the popular operating system
- 20040107 [WayBack] The history of calling conventions, part 2 – The Old New Thing
- 20040108 [WayBack] The history of calling conventions, part 3 – The Old New Thing
- 20040115 [WayBack] What can go wrong when you mismatch the calling convention? – The Old New Thing
- 20040102 [WayBack] The history of calling conventions, part 1 – The Old New Thing
- 20040127 [WayBack] Some reasons not to do anything scary in your DllMain – The Old New Thing
- 20040130 [WayBack] The format of string resources – The Old New Thing
- 20040202 [WayBack] The management of memory for resources in 16-bit Windows – The Old New Thing
- 20040203 [WayBack] Mismatching scalar and vector new and delete – The Old New Thing
- 20040204 [WayBack] Answers to exercises – mismatching new/delete – The Old New Thing
- 20040205 [WayBack] The layout of a COM object – The Old New Thing
The Win32 COM calling convention specifies the layout of the virtual method table (vtable) of an object. If a language/compiler wants to support COM, it must lay out its object in the specified manner so other components can use it.
It is no coincidence that the Win32 COM object layout matches closely the C++ object layout. Even though COM was originally developed when C was the predominant programming language, the designers saw fit to “play friendly” with the up-and-coming new language C++.
- 20040216 [WayBack] The arms race between programs and users – The Old New Thing
- 20040218 [WayBack] Why are RECTs endpoint-exclusive? – The Old New Thing
the best way to interpret this is to view pixels as living between coordinates, not at them. For example, here’s a picture of the pixel that lives between (10,10) and (11,11). (In other words, this pixel is the rectangle (10,10)-(11,11).)
10 11 10 11 With this interpretation, the exclusion of the endpoint becomes much more natural. For example, here’s the rectangle (10,10)-(13,12):
10 11 12 13 10 11 12 Observe that this rectangle starts at (10,10) and ends at (13,12), just like its coordinates say.
- WayBack: Alvy Microsoft Memos
- Image Compositing Fundamentals
- A Sprite Theory of Image Computing
- A Pixel is Not a Little Square, a Pixel is Not a Little Square, a Pixel is Not a Little Square! (And a Voxel is Not a Little Cube)
- Alpha and the History of Digital Compositing
- Varieties of Digital Painting
- Gamma Correction
- Digital Paint Systems: Historical Overview
- Should Alpha Be Nonlinear If RGB Is?
- Eigenpolygon Decomposition of Polygons
- Image Compositing Fundamentals
- WayBack: Alvy Microsoft Memos
- 20040220 [WayBack] Why do I get a QueryInterface(IID_IMarshal) and then nothing? – The Old New Thing
This is a sure sign that you didn’t register your CLSID properly; most likely you forgot to set your threading model properly. (And if you fail to specify a threading model at all, then you get the dreaded “main” threading model.)
If somebody tries to create a COM object from a thread whose model is incompatible with the threading model of the COM object, then a whole bunch of marshalling stuff kicks in. And if the marshalling stuff isn’t there, then COM can’t use your object.
- WayBack: Concurrency Management: Threading Models Understanding the Distributed Object Component Model (DCOM) Architecture
- 20040227 [WayBack] The correct order for disabling and enabling windows – The Old New Thing
The correct order for destroying a modal dialog is
- Re-enable the owner.
- Destroy the modal dialog.
This time, when the modal dialog is destroyed, the window manager looks to the owner and hey this time it’s enabled, so it inherits activation.
No flicker. No interloper.
- 20040311 [WayBack] Why are dialog boxes initially created hidden? – The Old New Thing
- 20040316 [WayBack] Why do text files end in Ctrl+Z? – The Old New Thing
- 20040326 [WayBack] The ways people mess up IUnknown::QueryInterface – The Old New Thing
- 20040224 [WayBack] What’s so special about the desktop window? – The Old New Thing
- Destructors:
- 20040614 [WayBack] What is the difference between HINSTANCE and HMODULE? – The Old New Thing
- Dialog templates:
- 20040617 [WayBack] The evolution of dialog templates – Introduction – The Old New Thing
- 20040618 [WayBack] The evolution of dialog templates – 16-bit Classic Templates – The Old New Thing
- 20040621 [WayBack] The evolution of dialog templates – 32-bit Classic Templates – The Old New Thing
- 20040622 [WayBack] The evolution of dialog templates – 16-bit Extended Templates – The Old New Thing
- 20040623 [WayBack] The evolution of dialog templates – 32-bit Extended Templates – The Old New Thing
- 20040624 [WayBack] The evolution of dialog templates – Summary – The Old New Thing
- 20040629 [WayBack] The difference between thread-safety and re-entrancy – The Old New Thing
- 20040705 [WayBack] What’s the difference between SHGetMalloc, SHAlloc, CoGetMalloc, and CoTaskMemAlloc – The Old New Thing
- 20040720 [WayBack] Querying information from an Explorer window – The Old New Thing
- 20040802 [WayBack] How to set focus in a dialog box – The Old New Thing
- 20040804 [WayBack] Why .shared sections are a security hole – The Old New Thing
- 20040804 [WayBack] Never leave focus on a disabled control – The Old New Thing
- Hosting IContextMenu
- 20040920 [WayBack] How to host an IContextMenu, part 1 – Initial foray – The Old New Thing
- 20040921 [WayBack] Pitfalls in handling the WM_CONTEXTMENU message – The Old New Thing
The second subtlety of the WM_CONTEXTMENU message is the recognition that context menus can be invoked from the keyboard, not just by the mouse. If you have a 104-key keyboard, you will probably have a menu key to the right of your space bar. (Laptop owners: You’re on your own. Laptop keyboards are hardly standardized.) Alternatively, you can type Shift+F10 to get the same effect.
When the user invokes a context menu from the keyboard, the x and y coordinates are both -1. In this case, you should display the context menu for the currently-selected item (or items, if a multiple selection is active). If you miss this detail, then you will end up hit-testing against (-1, -1) and probably not find anything.
- 20040922 [WayBack] How to host an IContextMenu, part 2 – Displaying the context menu – The Old New Thing
- 20040923 [WayBack] How to host an IContextMenu, part 3 – Invocation location – The Old New Thing
- 20040924 [WayBack] How to host an IContextMenu, part 4 – Key context – The Old New Thing
- 20040927 [WayBack] How to host an IContextMenu, part 5 – Handling menu messages – The Old New Thing
- 20040928 [WayBack] How to host an IContextMenu, part 6 – Displaying menu help – The Old New Thing
- 20040929 [WayBack] What does boldface on a menu mean? – The Old New Thing
- 20040930 [WayBack] How to host an IContextMenu, part 7 – Invoking the default verb – The Old New Thing
- 20041001 [WayBack] How to host an IContextMenu, part 8 – Optimizing for the default command – The Old New Thing
- 20041004 [WayBack] How to host an IContextMenu, part 9 – Adding custom commands – The Old New Thing
- 20041005 [WayBack] The macros for declaring and implementing COM interfaces – The Old New Thing
- 20041006 [WayBack] How to host an IContextMenu, part 10 – Composite extensions – groundwork – The Old New Thing
- 20041007 [WayBack] How to host an IContextMenu, part 11 – Composite extensions – composition – The Old New Thing
- 20041112 [WayBack] Will dragging a file result in a move or a copy? – The Old New Thing
- If
Ctrl
+Shift
are held down, then the operation creates a shortcut. - If
Shift
is held down, then the operation is a move. - If
Ctrl
is held down, then the operation is a copy. - If no modifiers are held down and the source and destination are on the same drive, then the operation is a move.
- If no modifiers are held down and the source and destination are on different drives, then the operation is a copy.
- If
- 20041119 [WayBack] The various ways of sending a message – The Old New Thing
- 20041122 [WayBack] When people ask for security holes as features: World-writable files – The Old New Thing
- 20041126 [WayBack] Simple things you can do with the ShellExecuteEx function – The Old New Thing
- 20041130 [WayBack] What’s the difference between GetKeyState and GetAsyncKeyState? – The Old New Thing
- Dragging a shell object
- 20041206 [WayBack] Dragging a shell object, part 1: Getting the IDataObject – The Old New Thing
- 20041207 [WayBack] Dragging a shell object, part 2: Enabling the Move operation – The Old New Thing
- 20041208 [WayBack] Dragging a shell object, part 3: Detecting an optimized move – The Old New Thing
- 20041209 [WayBack] Dragging a shell object, part 4: Adding a prettier drag icon – The Old New Thing
- 20041210 [WayBack] Dragging a shell object, part 5: Making somebody else do the heavy lifting – The Old New Thing
- 20041213 [WayBack] Why do I get E_NOINTERFACE when creating an object that supports that interface? – The Old New Thing
A common source of this is attempting to use COM objects provided by the shell from a multi-threaded apartment. Remember that shell COM objects are, for the most part, apartment-threaded, not free-threaded. If you want to use shell objects, you should do so from single-threaded apartments.
- Calling conventions
- 2005
- 20050207 [WayBack] Why does DS_SHELLFONT = DS_FIXEDSYS | DS_SETFONT? – The Old New Thing
- 20050209 [WayBack] The dangers of filtering window messages – The Old New Thing
- 20050215 [WayBack] You cannot globally reserve user-mode address space – The Old New Thing
- 20050217 [WayBack] MsgWaitForMultipleObjects and the queue state – The Old New Thing
- [WayBack] Modality – The Old New Thing
- 20050218 [WayBack] Modality, part 1: UI-modality vs code-modality – The Old New Thing
- 20050221 [WayBack] Modality, part 2: Code-modality vs UI-modality – The Old New Thing
- 20050222 [WayBack] Modality, part 3: The WM_QUIT message – The Old New Thing
- 20050223 [WayBack] Modality, part 4: The importance of setting the correct owner for modal UI – The Old New Thing
- 20050224 [WayBack] Modality, part 5: Setting the correct owner for modal UI – The Old New Thing
- 20050228 [WayBack] Modality, part 6: Interacting with a program that has gone modal – The Old New Thing
- 20050301 [WayBack] Modality, part 7: A timed MessageBox, the cheap version – The Old New Thing
- 20050304 [WayBack] Modality, part 8: A timed MessageBox, the better version – The Old New Thing
- 20050314 [WayBack] A subtlety in restoring previous window position – The Old New Thing
- The dialog manager:
- 20050329 [WayBack] The dialog manager, part 1: Warm-ups – The Old New Thing
- 20050330 [WayBack] The dialog manager, part 2: Creating the frame window – The Old New Thing
- 20050331 [WayBack] The dialog manager, part 3: Creating the controls – The Old New Thing
- 20050401 [WayBack] The dialog manager, part 4: The dialog loop – The Old New Thing
- 20050404 [WayBack] The dialog manager, part 5: Converting a non-modal dialog box to modal – The Old New Thing
- 20050405 [WayBack] The dialog manager, part 6: Subtleties in message loops – The Old New Thing
- 20050406 [WayBack] The dialog manager, part 7: More subtleties in message loops – The Old New Thing
- 20050408 [WayBack] The dialog manager, part 9: Custom accelerators in dialog boxes – The Old New Thing
- 20050418 [WayBack] What is the HINSTANCE passed to CreateWindow and RegisterClass used for? – The Old New Thing
- 20050422 [WayBack] The new scratch program – The Old New Thing
- 20050425 [WayBack] What is the HINSTANCE passed to SetWindowsHookEx used for? – The Old New Thing
- 20050426 [WayBack] Thread messages are eaten by modal loops – The Old New Thing
- 20050427 [WayBack] Watching thread messages disappear – The Old New Thing
- 20050428 [WayBack] Rescuing thread messages from modal loops via message filters – The Old New Thing
- 20050727 [WayBack] When the normal window destruction messages are thrown for a loop – The Old New Thing
- 20050607 [WayBack] What if two programs did this? – The Old New Thing
- 20050623 [WayBack] Why does the CreateProcess function do autocorrection? – The Old New Thing
Your choice is between “being pure and unpopular” or “being pragmatic and popular”. Look at all the wonderful technologies that died for lack of popularity despite technical superiority. Sony Betamax. Mattel Intellivision. (And, in the United States: The metric system.)
- 20050627 [WayBack] Why are there broadcast-based mechanisms in Windows? – The Old New Thing
- 20050630 [WayBack] Beware of roaming user profiles – The Old New Thing
- 20050705 [WayBack] Using script to query information from Internet Explorer windows – The Old New Thing
- 20050907 [WayBack] Why aren’t low-level hooks injected? – The Old New Thing
- 20050912 [WayBack] Understanding the consequences of WAIT_ABANDONED – The Old New Thing
- 20051004 [WayBack] Consequences of the scheduling algorithm: Sleeping doesn’t always help – The Old New Thing
More often I see the reverse of the “Low priority threads can run even when higher priority threads are running” problem. Namely, people who think that
Sleep(0)
is a clean way to yield CPU. For example, they might have run out of things to do and merely wish to wait for another thread to produce some work.…
The best thing to do is to wait on a proper synchronization object so that your thread goes to sleep until there is work to do. If you can’t do that for some reason, at least sleep for a nonzero amount of time. That way, for that brief moment, your thread is not runnable and other threads—including lower-priority threads—get a chance to run. (This will also reduce power consumption somewhat, though not as much as waiting on a proper synchronization object.)
- Thread affinity of user interface objects
- 20051010 [WayBack] Thread affinity of user interface objects, part 1: Window handles – The Old New Thing
- 20051011 [WayBack] Thread affinity of user interface objects, part 2: Device contexts – The Old New Thing
- 20051012 [WayBack] Thread affinity of user interface objects, part 3: Menus, icons, cursors, and accelerator tables – The Old New Thing
- 20051013 [WayBack] Thread affinity of user interface objects, part 4: GDI objects and other notes on affinity – The Old New Thing
- 20051014 [WayBack] Thread affinity of user interface objects, part 5: Object clean-up – The Old New Thing
- 20051021 [WayBack] Why is it even possible to disable the desktop anyway? – The Old New Thing
- 2006
- 20060124 [WayBack] Performance consequences of polling – The Old New Thing
- 20060125 [WayBack] You can call MsgWaitForMultipleObjects with zero handles – The Old New Thing
- 20060126 [WayBack] Pumping messages while waiting for a period of time – The Old New Thing
- 20060210 [WayBack] The dangers of sleeping on a UI thread – The Old New Thing
Note that many people overlook that calling
CoInitialize
(possibly indirectly) to initialize a thread for STA creates a hidden window in order to perform marshalling. Consequently, a thread that is running in a single-threaded apartment must pump messages. Failing to do so will result in mysterious system-wide stalls due to the unresponsive window. - 20060220 [WayBack] Why does my program run faster if I click and hold the caption bar? – The Old New Thing
I used a variation of the technique demonstrated here to speedup the GExperts search: it was spending most of the CPU on updating the UI.
- 20060221 [WayBack] In pursuit of the message queue – The Old New Thing
- 20060222 [WayBack] The performance cost of reading a registry key – The Old New Thing
- 20060302 [WayBack] Restating the obvious about the WM_COMMAND message – The Old New Thing
- 20060316 [WayBack] Why does the version 6 animation control not use a background thread? – The Old New Thing
- 20060330 [WayBack] How would you solve this compatibility problem: Network interoperability – The Old New Thing
- 20060405 [WayBack] Adding flags to APIs to work around driver bugs doesn’t scale – The Old New Thing
- 20060407 [WayBack] Computing over a high-latency network means you have to bulk up – The Old New Thing
- 20060410 [WayBack] Be very careful if you decide to change the rules after the game has ended – The Old New Thing
- 20060419 [WayBack] Adding a new flag to enable behavior that previously was on by default – The Old New Thing
- 20060503 [WayBack] The alertable wait is the non-GUI analog to pumping messages – The Old New Thing
- 20060505 [WayBack] What can I do with the HINSTANCE returned by the ShellExecute function? – The Old New Thing
- 20060601 [WayBack] What does the CS_OWNDC class style do? – The Old New Thing
- 20060621 [WayBack] Psychic debugging: Understanding DDE initiation – The Old New Thing
- 20060703 [WayBack] Security: Don’t forget to initialize the stuff you don’t care about – The Old New Thing
- 20060809 [WayBack] How were window hooks implemented in 16-bit Windows? – The Old New Thing
- 20060823 [WayBack] Environment variable expansion occurs when the command is read – The Old New Thing
- WayBack: Blogs – Things I’ve Learned – Site Home – TechNet Blogs:
errorlevel in for loop returns exit code of iterating statement
(do not use
%errorlevel%
, use a plainerrorlevel
comparison instead)
- WayBack: Blogs – Things I’ve Learned – Site Home – TechNet Blogs:
- 20060911 [WayBack] If you ask a Yes/No question, make sure the user also knows what happens when they say No – The Old New Thing
- 20060918 [WayBack] Sometimes my psychic powers are weak – The Old New Thing
- 20060922 [WayBack] Things you already know: How do I wait until my dialog box is displayed before doing something? – The Old New Thing
- 20060925 [WayBack] Waiting until the dialog box is displayed before doing something – The Old New Thing
- 20060926 [WayBack] Isn’t DDE all asynchronous anyway? – The Old New Thing
- 20061003 [WayBack] There’s a reason why envelopes have backs – The Old New Thing
- 20061102 [WayBack] Make sure you disable the correct window for modal UI – The Old New Thing
- 20061108 [WayBack] How do I test that return value of ShellExecute against 32? – The Old New Thing
- 20061205 [WayBack] How do I find all files with at least one space in their name? – The Old New Thing
- 20061218 [WayBack] Do not write in-process shell extensions in managed code – The Old New Thing
Update 2013: Now that version 4 of the .NET Framework supports in-process side-by-side runtimes, is it now okay to write shell extensions in managed code? The answer is still no.
- 2007
- 20070112 [WayBack] How do I print the contents of a rich text control? – The Old New Thing
- 20070904 [WayBack] Does creating a thread from DllMain deadlock or doesn’t it? – The Old New Thing
This deadlock is much more commonly seen in
DLL_PROCESS_DETACH
, where a DLL wants to shut down its worker threads and wait for them to clean up before it unloads itself. You can’t wait for a thread insideDLL_PROCESS_DETACH
because that thread needs to send out theDLL_THREAD_DETACH
notifications before it exits, which it can’t do until yourDLL_PROCESS_DETACH
handler returns.(It is for this thread cleanup case that the function
FreeLibraryAndExitThread
was created.)- [WayBack] DLL Dynamic Link Library Best Practices
Guidelines for developing robust, portable, and extensible dynamic link libraries (DLLs) for the Windows family of operating systems.
- [WayBack] DLL Dynamic Link Library Best Practices
20070130 [WayBack] Unusual uses for a ball-point pen: Breaking into the debugger – The Old New Thing
Before PCI there was ISA. The pinout for ISA slots had one very convenient property: If you shorted the last two pins in an open ISA slot, you generated an NMI.
…
If you had the Windows 95 debugger connected to the system (known as
WDEB386
), it caught the NMI and broke into the debugger. Doesn’t matter if interrupts were disabled; you got your debugger. NMI stands for “non-maskable interrupt” and it’s the “non-maskable” part that is important here, for it means that there’s nothing that will prevent it from happening¹. Very handy if a device driver got itself stuck in an infinite loop. You could tell the real device driver developers from the posers by seeing who carried a ball-point pen with them. (I’ll talk more about NMI in a future entry.)- Dump Switch Support for Windows:
Microsoft Windows 2000, Windows XP, and Windows NT 4.0, Service Pack 4 (SP4) include support for dump switches.
- Dump Switch Support for Windows:
- 20070226 [WayBack] Please feel free to stop using DDE – The Old New Thing
- 20070226 [WayBack] The politician’s fallacy and the politician’s apology – The Old New Thing
- 20070426 [WayBack] Using the “gu” debugger command to find the infinite loop – The Old New Thing (note
gu
is the “go up” command) - 20070502 [WayBack] The old-fashioned theory on how processes exit – The Old New Thing
- 20070503 [WayBack] Quick overview of how processes exit on Windows XP – The Old New Thing
- 20070504 [WayBack] How my lack of understanding of how processes exit on Windows XP forced a security patch to be recalled – The Old New Thing
- 20070521 [WayBack] Don’t be helpless: I don’t know anything about MFC modal loops, but unlike some people, I’m not afraid to find out – The Old New Thing
- 20070523 [WayBack] Suggestion Box 3 – The Old New Thing
- 20070727 [WayBack] Don’t just grab the foreground window and host UI on it – The Old New Thing
- 20071018 [WayBack] Win32 user interface work is inherently single-threaded – The Old New Thing
- 20071121 [WayBack] Hidden gotcha: The command processor’s AutoRun setting – The Old New Thing
- 20071205 [WayBack] Welcome to the Microsoft email culture – The Old New Thing
- 20071217 [WayBack] How did wildcards work in MS-DOS? – The Old New Thing
- 20071231 [WayBack] Why aren’t console windows themed on Windows XP? – The Old New Thing
- 2008
- 20080116 [WayBack] Use WM_WINDOWPOSCHANGING to intercept window state changes – The Old New Thing
- 20080220 [WayBack] There can be more than one (or zero): Converting a process to a window – The Old New Thing
- Drag and drop:
- 20080307 [WayBack] The art of losing things: Keep moving them around – The Old New Thing
- 20080311 [WayBack] What a drag: Dragging text – The Old New Thing
- 20080318 [WayBack] What a drag: Dragging a virtual file (HGLOBAL edition) – The Old New Thing
- 20080319 [WayBack] What a drag: Dragging a virtual file (IStream edition) – The Old New Thing
- 20080312 [WayBack] What a drag: Dragging a Uniform Resource Locator (URL) – The Old New Thing
- 20080416 [WayBack] Raymond’s reading list: The Mythical Man-Month, The Design of Everyday Things, and Systemantics – The Old New Thing
- 20080421 [WayBack] Windows doesn’t close windows when a user logs off; that’s your call – The Old New Thing
On
WM_CLOSE
,WM_ENDSESSION
, andWM_QUERYENDSESSION
. - 20080424 [WayBack] User interface code + multi-threaded apartment = death – The Old New Thing
- 20080506 [WayBack] Psychic debugging: Why does ExitProcess(1) produce an exit code of zero? – The Old New Thing
- 20080520 [WayBack] The Phantom Bug: Why doesn’t MessageBox work from my WM_NCDESTROY handler? – The Old New Thing
- 20080523 [WayBack] What does TranslateAccelerator do? – The Old New Thing
- 20080528 [WayBack] Reading a contract from the other side: SHSetInstanceExplorer and SHGetInstanceExplorer – The Old New Thing
- 20080724 [WayBack] Reading a contract from the other side: Simulating a drop – The Old New Thing
- 20080728 [WayBack] How can SIGINT be safely delivered on the main thread? – The Old New Thing
- 20080808 [WayBack] If you return FALSE from DLL_PROCESS_ATTACH, will you get a DLL_PROCESS_DETACH? – The Old New Thing
- 20081016 [WayBack] Psychic debugging: Why your thread is spending all its time processing meaningless thread timers – The Old New Thing
what a null window handle in a
WM_TIMER
message means: These are thread timers, timers which are associated not with a window but with a thread. You create a thread timer by calling theSetTimer
function and passingNULL
as the window handle. Thread timer messages arrive in the message queue, and theDispatchMessage
function calls the timer procedure specified by the messageLPARAM
. If theLPARAM
of a thread timer message is zero, then dispatching the message consists merely of throwing it away. (If there were a window handle, then the message would be delivered to the window procedure, but there isn’t one, so there’s nothing else that can be done.) - 20081021 [WayBack] Strange things happen when you let people choose their own name, part 1 – The Old New Thing
- 20081117 [WayBack] Why bother with RegisterWaitForSingleObject when you have MsgWaitForMultipleObjects? – The Old New Thing
- 20081211 [WayBack] Don’t use global state to manage a local problem – The Old New Thing
- 20081223 [WayBack] Why isn’t there a SendThreadMessage function? – The Old New Thing
- 2009
- 20090126 [WayBack] But then we ran into problems when we started posting 10,000 messages per second – The Old New Thing
- 20090220 [WayBack] Foreground activation permission is like love: You can’t steal it, it has to be given to you – The Old New Thing
- 20090226 [WayBack] Pressing a registered hotkey gives you the foreground activation love – The Old New Thing
- 20090316 [WayBack] Why does the MoveWindow function let you suppress repainting? – The Old New Thing
- 20090420 [WayBack] The dangers of destroying a window while it is processing a sent message – The Old New Thing
- 20090727 [WayBack] Polling by sleeping versus polling by waiting with a timeout – The Old New Thing
- 20090930 [WayBack] Why do messages posted by PostThreadMessage disappear? – The Old New Thing
- 20091021 [WayBack] Please, sir take a seat, sit anywhere you like, but oh, no, not there, rats – The Old New Thing
- 20091113 [WayBack] You thought reasoning about signals was bad, reasoning about a total breakdown of normal functioning is even worse – The Old New Thing
- 20091202 [WayBack] A shell extension is a guest in someone else’s house; don’t go changing the carpet – The Old New Thing
- 2010
- 20100122 [WayBack] During process termination, the gates are now electrified – The Old New Thing
- 20100215 [WayBack] Private classes, superclassing, and global subclassing – The Old New Thing
- 20100222 [WayBack] Custom navigation in dialog boxes, redux – The Old New Thing
- 2010030920100309 [WayBack] PSM_ISDIALOGMESSAGE is to modeless property sheets as IsDialogMessage is to modeless dialog boxes – The Old New Thing
- 20100325 [WayBack] WaitForInputIdle should really be called WaitForProcessStartupComplete – The Old New Thing
- 20100430 [WayBack] If it’s not yours, then don’t mess with it without permission from the owner – The Old New Thing
- 20100503 [WayBack] How do I accept files to be opened via IDropTarget instead of on the command line? – The Old New Thing
- 20100510 [WayBack] Why can programs empty the clipboard when they start up? – The Old New Thing
- 20100517 [WayBack] If Windows 3.11 required a 32-bit processor, why was it called a 16-bit operating system? – The Old New Thing
- 20100720 [WayBack] Suggestion Box 4 – The Old New Thing
- 20100930 [WayBack] Why doesn’t the TAB key work on controls I’ve marked as WS_TABSTOP? – The Old New Thing
- 20101007 [WayBack] Why does TaskDialog return immediately without showing a dialog? – The Old New Thing
- 20101008 [WayBack] Why does TaskDialog return immediately without showing a dialog? – Answer – The Old New Thing
- 20101025 [WayBack] When you call a function, your code doesn’t resume execution until that function returns – The Old New Thing
- 20101203 [WayBack] ZOMG! This program is using 100% CPU!1! Think of the puppies!!11!!1!1!eleven – The Old New Thing
- 20101115 [WayBack] The program running in a console decides what appears in that console – The Old New Thing
- 20100122 [WayBack] During process termination, the gates are now electrified – The Old New Thing
- 2011
- 20110120 [WayBack] How to turn off the exception handler that COM “helpfully” wraps around your server – The Old New Thing
- 20110218 [WayBack] WM_NCHITTEST is for hit-testing, and hit-testing can happen for reasons other than the mouse being over your window – The Old New Thing
- 20110304 [WayBack] The window manager needs a message pump in order to call you back unexpectedly – The Old New Thing
- 20110919 [WayBack] The clipboard viewer linked list is no longer the responsibility of applications to maintain, unless they want to – The Old New Thing
Instead of using the clipboard viewer chain, just add yourself as a clipboard format listener via
AddClipboardFormatListener
. Once you’ve done that, the system will post you aWM_CLIPBOARDUPDATE
message when the contents of the clipboard have changed, and you can respond accordingly. When you’re done, callRemoveClipboardFormatListener
. - 20110912 [WayBack] Is this a really bug with CreateWindowEx or am I just confused? – The Old New Thing
- 20110915 [WayBack] What happens to a sent message when SendMessageTimeout reaches its timeout? – The Old New Thing
But wait, how do I know when the window procedure is done? The
SendMessageTimeout
function doesn’t tell me! Yup, that’s right. If you need to do cleanup after message processing is complete, you should use theSendMessageCallback
function, which calls you back when the receiving thread completes message processing. When the callback fires, that’s when you do your cleanup. - 20110916 [WayBack] Why can’t I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout? – The Old New Thing
- 20110926 [WayBack] Sending a window a WM_DESTROY message is like prank calling somebody pretending to be the police – The Old New Thing
- 20111107 [WayBack] The life story of the SwitchToThisWindow function – The Old New Thing
- 20111118 [WayBack] Why does Internet Explorer not call DLL_PROCESS_DETACH on my DLL when I call ExitProcess? – The Old New Thing
- 20111219 [WayBack] Paint messages will come in as fast as you let them – The Old New Thing
- 2012
- 20120314 [WayBack] How do I get mouse messages faster than WM_MOUSEMOVE? – The Old New Thing
- 20120413 [WayBack] You already know the answer since you do it yourself – The Old New Thing
- 20120416 [WayBack] Why do we need IsDialogMessage at all? – The Old New Thing
- 20120604 [WayBack] Why does PrintWindow hate CS_PARENTDC? Because EVERYBODY hates CS_PARENTDC! – The Old New Thing
- 20120802 [WayBack] Exiting a batch file without exiting the command shell -and- batch file subroutines – The Old New Thing
In other words,
goto :eof
is thereturn
statement for batch file subroutines. - 20120910 [WayBack] When you transfer control across stack frames, all the frames in between need to be in on the joke – The Old New Thing
- 20121003 [WayBack] How do I suppress the default animation that occurs when I hide or show a window? – The Old New Thing
- 20121022 [WayBack] How do you come up with new shortcut keys? – The Old New Thing
- 20121024 [WayBack] You can’t use the WM_USER message in a dialog box – The Old New Thing
- 20121206 [WayBack] Replaying input is not the same as reprocessing it – The Old New Thing
- 2013
- 20130208 [WayBack] For the Nitpickers: Enhanced-mode Windows 3.0 didn’t exactly run a copy of standard-mode Windows inside the virtual machine – The Old New Thing
- 20130222 [WayBack] Now that version 4 of the .NET Framework supports in-process side-by-side runtimes, is it now okay to write shell extensions in managed code? – The Old New Thing
Although version 4 addresses the side-by-side issue, it is still the case that the .NET Framework is a high-impact runtime, and that there are various part of COM interop in the .NET Framework that are not suitable for use in an extension model designed around native code.
Note that managed code remains acceptable for out-of-process extensions.
- 20130419 [WayBack] Why does CoCreateInstance work even though my thread never called CoInitialize? The curse of the implicit MTA – The Old New Thing
- 20130322 [WayBack] When will GetMessage return -1? – The Old New Thing
- 20130523 [WayBack] Even though mouse-move, paint, and timer messages are generated on demand, it’s still possible for one to end up in your queue – The Old New Thing
- 20130605 [WayBack] When you share an input queue, you have to wait your turn – The Old New Thing
- 20130606 [WayBack] A pathological program which ignores the keyboard, and understanding the resulting behavior based on what we know about the synchronous input – The Old New Thing
- 20130619 [WayBack] AttachThreadInput is like taking two threads and pooling their money into a joint bank account, where both parties need to be present in order to withdraw any money – The Old New Thing
- 20130627 [WayBack] Once you return from the WM_ENDSESSION message, your process can be terminated at any time – The Old New Thing
- 20130905 [WayBack] Why are my posted messages getting lost when the user drags my window around? – The Old New Thing
- 20130930 [WayBack] Playing a sound every time the foreground window changes – The Old New Thing
- 20131008 [WayBack] I wrote FAT on an airplane, for heaven’s sake – The Old New Thing
- 20131009 [WayBack] Using the TAB key to navigate in non-dialogs, redux – The Old New Thing
- 20131129 [WayBack] Why can’t I create my dialog with DialogBox, DialogBoxParam, CreateDialog, CreateDialogParam, or the indirect versions of same? – The Old New Thing
- 2014
- 20140117 [WayBack] Psychic debugging: Why messages aren’t getting processed by your message pump – The Old New Thing
- 20140328 [WayBack] The dangers of buffering up posted messages and then reposting them later – The Old New Thing
- 20140404 [WayBack] It’s bad enough for a guest to demolish the host’s house; demolishing an unrelated person’s house is taking it to a whole new level – The Old New Thing
- 20140514 [WayBack] The mystery of the icon that never appears – The Old New Thing
- Ctrl+Alt+Del week:
- 20140902 [WayBack] Who wrote the text for the Ctrl+Alt+Del dialog in Windows 3.1? – The Old New Thing
- 20140908 [WayBack] Piping to notepad – The Old New Thing
- 20140909 [WayBack] Steve Ballmer did not write the text for the blue screen of death – The Old New Thing
- 20140910 [WayBack] I wrote the original blue screen of death, sort of – The Old New Thing
- 20140911 [WayBack] The history of Win32 critical sections so far – The Old New Thing
- 20140912 [WayBack] What did Windows 3.1 do when you hit Ctrl+Alt+Del? – The Old New Thing
- 20140521 [WayBack] Dialog boxes return focus to the control that had focus when you last switched away; how do I get in on that action for my own windows? – The Old New Thing
- 20140522 [WayBack] Why does my radio button group selection get reset each time my window regains activation? – The Old New Thing
- 20140617 [WayBack] Who would ever write a multi-threaded GUI program? – The Old New Thing
- 20140922 [WayBack] Receiving a notification any time the selection changes in an Explorer window – The Old New Thing
- 20141016 [WayBack] If only DLLs can get DllMain notifications, how can an EXE receive a notification when a thread is created (for example)? – The Old New Thing
The trick here is to hire a lackey.
Create a helper DLL, called, say,
LACKEY.DLL
. Your EXE links to the lackey, and the lackey’s job is to forward allDllMain
notifications back to your EXE. The DLL would naturally have to have a way for your EXE to provide the callback address, so you might have a functionRegisterLackeyCallback
. - 20141017 [WayBack] When are global objects constructed and destructed by Visual C++? – The Old New Thing
When does it run? Constructor Destructor Global object in EXE C runtime startup code C runtime DLL hired lackey Global object in DLL C runtime DLL_PROCESS_ATTACH
prior toDllMain
C runtime DLL_PROCESS_DETACH
afterDllMain
returns - 20141024 [WayBack] Debugging a hang: Chasing the wait chain inside a process – The Old New Thing
- 20141203 [WayBack] What happens if I don’t paint when I get a WM_PAINT message? – The Old New Thing
- 20141204 [WayBack] If my WM_TIMER handler takes longer than the timer period, will my queue fill up with WM_TIMER messages? – The Old New Thing
- 20141205 [WayBack] Killing a window timer prevents the WM_TIMER message from being generated for that timer, but it doesn’t retroactively remove ones that were already generated – The Old New Thing
- 2015
- 20150514 [WayBack] Low-level hooks have thread affinity, so make sure you keep an eye on the thread – The Old New Thing
- 20150924 [WayBack] How do I call SetTimer with a timer ID that is guaranteed not to conflict with any other timer ID? – The Old New Thing
- 20150928 [WayBack] What happens to lost timer messages if I don’t process them fast enough? – The Old New Thing
- 20151020 [WayBack] What is COM marshaling and how do I use it? – The Old New Thing
COM has this concept called “marshaling”, with one L. Basically, marshaling is the mechanism by which an object that is accessible to one apartment can be made accessible to another apartment.
Incomplete backgrounder on apartments: In COM, an apartment is a collection of threads that are treated as equivalent from a COM standpoint. The details of apartments aren’t important for today’s discussion, so let’s assume that all the apartments in question are single-threaded apartments (STA). Single-threaded apartments, as you might guess from their name, are apartments that consist of a single thread. In this world, the concepts of thread and apartment line up one-to-one, which makes discussion easier.
Incomplete backgrounder on threading models: Each COM object declares how it deals with threads. The most common cases areapartment model objects,¹ which can be used only on the thread that they were created on, and free-threaded objects, which can be used from any thread. Free-threaded objects are easier to use, but apartment model objects are much, much easier to write, since you don’t have any of that troublesome multi-threading to deal with.
- 20151021 [WayBack] What are the rules for CoMarshalInterThreadInterfaceInStream and CoGetInterfaceAndReleaseStream? – The Old New Thing
- 20151116 [WayBack] How can I get notified when the cursor changes? – The Old New Thing
- 20151204 [WayBack] Why did disabling interrupts cause Windows 95 to hang? – The Old New Thing
- 2016
- 20160101 [WayBack] If you want to receive a message that is broadcast to top-level windows, you need a top-level window – The Old New Thing
- 20160226 [WayBack] Changing a loop into a promise or task chain – The Old New Thing
- 20160408 [WayBack] Why does FindExecutable behave erratically for files with extensions longer than three characters? (And what can you do about it?) – The Old New Thing
- 20160505 [WayBack] How can I write an unkillable program, redux – The Old New Thing
If you want to make sure the user goes home, you can have the service lock the workstation and set a restricted logon policy so the user cannot log back in until 9am the next morning. The service can inject a program into the session to display a countdown timer. In this case, the user can terminate the countdown timer app all they want; that’s not going to stop the workstation from being locked. They’re just shooting the messenger.
- 20160624 [WayBack] Why is my message queue full of WM_TIMER messages? – The Old New Thing
- 20160811 [WayBack] On the importance of making sure WaitForInputIdle doesn’t think you’re idle, episode 1 – The Old New Thing
- 20160812 [WayBack] On the importance of making sure WaitForInputIdle doesn’t think you’re idle, episode 2 – The Old New Thing
- 20160818 [WayBack] If I have a modeless dialog box with custom accelerators, which should I call first: IsDialogMessage or TranslateAccelerator – The Old New Thing
- 20160823 [WayBack] WaitOnAddress lets you create a synchronization object out of any data variable, even a byte – The Old New Thing
- 20161118 [WayBack] Why does calling SetForegroundWindow immediately followed by GetForegroundWindow not return the same window back? – The Old New Thing
- 2017
- 20170202 [WayBack] Are DDE and WM_COPYDATA related as IPC mechanisms? – The Old New Thing
- 20170221 [WayBack] Psychic debugging: Why does opening a command prompt always print a weird error message? – The Old New Thing
- 20170329 [WayBack] A brief discussion on how best to respond to the end-session messages – The Old New Thing
- 20170425 [WayBack] How do I kill a program that hung with an always-on-top fullscreen window? – The Old New Thing
- 20170602 [WayBack] How likely is it that a window will receive a WM_NULL message out of the blue? – The Old New Thing
- 2018
A truckload of “message loop” related posts on Old New Thing already gives the right impression: message handling is tough.
Not all related posts focus on the message loop: many have it as a side topic from for instance handling various messages, or performing async processing. As many application stacks (like ATL, MFC, VCL, WinForms, OWL and such) use the message processing to support asynchronous tasks.
Some focus on initialisation and termination of processes and threads, owner and parent-ship of Windows and their life time management, as all those are very much related on how and when to handle messages.
Others are only referenced from message loop posts, but still are important as they provide guidance to good software development and design practices.
Three key things on the Old New Thing posts:
- Most of them are centered around the Windows API. This focuses on the essentials (making them easier to follow), but also can make it harder as application stacks often encapsulate the Windows API, forcing you to learn how they do that and which parts can help you get your fingers behind they Windows API access.
- They usually refer to related Old New Thing posts, which makes it a easier (less hard) to figure out Windows API related challenges.
- The examples are usually centered around a sample application that started out in 2003 as a plain C example, but in 2005 got implemented as C++ example. Source for the latter is at [WayBack] functional/win32-scratch-program.cpp at master · okertanov/functional · GitHub.
The posts with these examples are bolded in the list.
–jeroen
Leave a Reply