HwndHost is not clipped inside ScrollViewer

I created a simple white control with a black border derived from HwndHost (named LightGrid) and added it to ScrollViewer along with some other controls (replaced with “…”) as shown below:

<ScrollViewer HorizontalScrollBarVisibility="Disabled">
            <ColumnDefinition Width="Auto" />
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        <Border Grid.Row="6" Grid.ColumnSpan="2" Visibility="Visible" Height="200">
            <nc:LightGrid />

It looks correctly in the lower scroll position, and it even can scroll inside ScrollViewer (it moves when I move the scroll bar), but when scrolled, it is not clipped so it obscures other controls:

It looks correctly in the lower scroll position image

There is some solution in the internet based on handling ScrollChangedEvent and manipulation with window region via SetWindowRgn Win32 function. It looks a bit scary and probably in practice it can produce some specific effects, so we should avoid using HwndHost inside ScrollViewer.

Below I provided all the source code of HwndHost based control, it uses some MFC control CHybridCtrl internally:

#pragma once

#include "GridCtrl.h"

using namespace System;
using namespace System::Windows;
using namespace System::Windows::Interop;
using namespace System::Runtime::InteropServices;

namespace NativeControls
    public ref class LightGrid : public HwndHost //,IKeyboardInputSink 


        virtual HandleRef BuildWindowCore(HandleRef hwndParent) override;

        virtual void DestroyWindowCore(HandleRef hwnd) override;

        //virtual void OnWindowPositionChanged(Rect rcBoundingBox) override;


        CHybridCtrl * pGrid = nullptr;

#include "stdafx.h"
#include "LightGrid.h"
#include "resource.h"

namespace NativeControls
    HandleRef LightGrid::BuildWindowCore(HandleRef hwndParent)
        pGrid = new CHybridCtrl();



        HWND hParent = (HWND)hwndParent.Handle.ToPointer();
        if (!pGrid->CreateEx(0, WS_CHILD | WS_VISIBLE | WS_BORDER,
            hParent, 1000))
            throw gcnew InvalidOperationException("Can not create CHybridCtrl.");

        return HandleRef(this, IntPtr(pGrid->m_hWnd));

    void LightGrid::DestroyWindowCore(HandleRef hwnd)
        // hwnd will be disposed for us

        delete pGrid;

    //void LightGrid::OnWindowPositionChanged(Rect rcBoundingBox)
    //    CRect rc(rcBoundingBox.Left, rcBoundingBox.Top, rcBoundingBox.Right, rcBoundingBox.Bottom);
    //    pGrid->MoveWindow(&rc);

Leave a Reply

Your email address will not be published. Required fields are marked *