[API Proposal]: Expose `HwndWrapper.AddHookLast` to external callers in `HwndSource`
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Background and motivation
WPF permits window hooks which run _before_ `HwndTarget` handles messages, but does not provide any way to handle messages after `HwndTarget` has processed the normal messages. This prevents replacing `DefWindowProc` with `DefMDIChildProc` or editing the result from `DefWindowProc` (e.g.: `WM_NCHITTEST`).
Calling `AddHookLast` by reflection verifies this new API is apparently sufficient to permit an `HwndSource` to act as an MDI Child.
### API Proposal
```csharp
public class HwndSource
{
public void AddHookLast(HwndSourceHook hook);
}
```
Sample implementation which neglects removal: https://github.com/mgaffigan/WpfMdiChildSample/blob/master/WpfMdiClientWindow/HwndSourceHacks.cs#L18
### API Usage
A full example is listed at https://github.com/mgaffigan/WpfMdiChildSample
```csharp
var winWPFContent = new HwndSource(/* snip setting up window with WS_EX_MDICHILD */);
winWPFContent.AddHookLast(MdiChildHook);
winWPFContent.RootVisual = new UserControl1();
private static nint MdiChildHook(nint hwnd, int msg, nint wParam, nint lParam, ref bool handled)
{
handled = true;
return DefMDIChildProcW(hwnd, msg, wParam, lParam);
}
```
### Alternative Designs
For the specific use case of enabling MDI Child Windows implemented in WPF, WinForms with `ElementHost` may be used with additional considerations.
Reimplementation of `HwndTarget` message handling in user code is likely to result in hard-to-diagnose subtle bugs.
### Risks
None identified due to opt-in and obscure use of the API.
The reference implementation linked above does not permit removal of a hook, which may violate expectations given the presence of `HwndSource.RemoveHook`.
Contributor guide
Assessment
This issue has not been assessed yet.