Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6973,6 +6973,18 @@ protected override void WndProc(ref Message m)
WmReflectNotify(ref m);
break;

case PInvokeCore.WM_CTLCOLOREDIT:
if (_labelEdit is not null && (HWND)m.LParamInternal == _labelEdit.HWND)
{
m.ResultInternal = (LRESULT)(nint)InitializeDCForWmCtlColor((HDC)(nint)m.WParamInternal, m.MsgInternal);
}
else
{
base.WndProc(ref m);
}

break;

case PInvokeCore.WM_KEYUP:
var key = (VIRTUAL_KEY)(uint)m.WParamInternal;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3161,6 +3161,17 @@ protected override unsafe void WndProc(ref Message m)
base.WndProc(ref m);
}

break;
case PInvokeCore.WM_CTLCOLOREDIT:
if (_labelEdit is not null && (HWND)m.LParamInternal == _labelEdit.HWND)
{
m.ResultInternal = (LRESULT)(nint)InitializeDCForWmCtlColor((HDC)(nint)m.WParamInternal, m.MsgInternal);
}
else
{
base.WndProc(ref m);
}

break;
case PInvokeCore.WM_HSCROLL:
base.WndProc(ref m);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6066,6 +6066,74 @@ public void ListView_GroupTaskLinkClick_EventHandling_ShouldBehaveAsExpected()
callCount.Should().Be(4);
}

[WinFormsTheory]
[InlineData(0x1E, 0x1E, 0x1E, 0xFF, 0xFF, 0xFF)] // Dark mode: dark bg, white text
[InlineData(0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00)] // Light mode: white bg, black text
public void ListView_WmCtlColorEdit_WithMatchingLabelEditHwnd_SetsDCColorsAndReturnsNonZeroBrush(int backR, int backG, int backB, int foreR, int foreG, int foreB)
{
// Regression test for issue #12042
Color expectedBackColor = Color.FromArgb(backR, backG, backB);
Color expectedForeColor = Color.FromArgb(foreR, foreG, foreB);

using SubListView listView = new()
{
LabelEdit = true,
View = View.Details,
Size = new Size(300, 200),
BackColor = expectedBackColor,
ForeColor = expectedForeColor
};

listView.Columns.Add(new ColumnHeader { Text = "Column 1", Width = 200 });
listView.Items.Add(new ListViewItem("Item 1"));
listView.CreateControl();

// Select the item then trigger label editing via the timer (same pattern used in
// ListView_OnMouseClick_EditLabel_AsExpected).
PInvoke.SetFocus(listView);
listView.Items[0].Selected = true;

Point itemLocation = listView.Items[0].Bounds.Location + new Size(1, 1);
PInvokeCore.PostMessage(listView, PInvokeCore.WM_LBUTTONUP, 0, PARAM.FromPoint(itemLocation));
PInvokeCore.SendMessage(listView, PInvokeCore.WM_LBUTTONDOWN, 1, PARAM.FromPoint(itemLocation));
PInvokeCore.SendMessage(listView, PInvokeCore.WM_TIMER,
(WPARAM)(nint)listView.TestAccessor.Dynamic.LVLABELEDITTIMER);

HWND editHwnd = (HWND)(nint)PInvokeCore.SendMessage(listView, PInvoke.LVM_GETEDITCONTROL);

if (editHwnd == HWND.Null)
{
PInvokeCore.SendMessage(listView, PInvoke.LVM_CANCELEDITLABEL);
return;
}

using GetDcScope hdc = new(editHwnd);
Message msg = Message.Create(
listView.Handle,
(int)PInvokeCore.WM_CTLCOLOREDIT,
(nint)(HDC)hdc,
(nint)editHwnd);

listView.WndProc(ref msg);

// 1. A valid (non-null) brush handle must be returned.
Assert.NotEqual(IntPtr.Zero, (nint)msg.ResultInternal);

// 2. DC text color must match the ForeColor we set on the control.
Color actualTextColor = PInvoke.GetTextColor(hdc);
Assert.Equal(
ColorTranslator.ToWin32(expectedForeColor),
ColorTranslator.ToWin32(actualTextColor));

// 3. DC background color must match the BackColor we set on the control.
Color actualBkColor = PInvoke.GetBkColor(hdc);
Assert.Equal(
ColorTranslator.ToWin32(expectedBackColor),
ColorTranslator.ToWin32(actualBkColor));

PInvokeCore.SendMessage(listView, PInvoke.LVM_CANCELEDITLABEL);
}

private class SubListViewItem : ListViewItem
{
public AccessibleObject CustomAccessibleObject { get; set; }
Expand Down Expand Up @@ -6171,6 +6239,8 @@ private class SubListView : ListView
public new void OnCacheVirtualItems(CacheVirtualItemsEventArgs e) => base.OnCacheVirtualItems(e);

public new void OnItemChecked(ItemCheckedEventArgs e) => base.OnItemChecked(e);

public new void WndProc(ref Message m) => base.WndProc(ref m);
}

private SubListView GetSubListViewWithData(View view, bool virtualMode, bool showGroups, bool withinGroup, bool createControl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7569,6 +7569,62 @@ public void TreeView_VisibleCount_MultipleNodes_ReturnsExpected(int nodeCount)
treeView.VisibleCount.Should().Be(5);
}

[WinFormsTheory]
[InlineData(0x1E, 0x1E, 0x1E, 0xFF, 0xFF, 0xFF)] // Dark mode: dark bg, white text
[InlineData(0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00)] // Light mode: white bg, black text
public void TreeView_WmCtlColorEdit_WithMatchingLabelEditHwnd_SetsDCColorsAndReturnsNonZeroBrush(int backR, int backG, int backB, int foreR, int foreG, int foreB)
{
// Regression test for issue #12042
Color expectedBackColor = Color.FromArgb(backR, backG, backB);
Color expectedForeColor = Color.FromArgb(foreR, foreG, foreB);

using SubTreeView treeView = new()
{
LabelEdit = true,
Size = new Size(200, 200),
BackColor = expectedBackColor,
ForeColor = expectedForeColor
};

treeView.Nodes.Add("Node0");
treeView.CreateControl();

treeView.Nodes[0].BeginEdit();
HWND editHwnd = (HWND)(nint)PInvokeCore.SendMessage(treeView, PInvoke.TVM_GETEDITCONTROL);

if (editHwnd == HWND.Null)
{
treeView.Nodes[0].EndEdit(cancel: true);
return;
}

using GetDcScope hdc = new(editHwnd);
Message msg = Message.Create(
treeView.Handle,
(int)PInvokeCore.WM_CTLCOLOREDIT,
(nint)(HDC)hdc,
(nint)editHwnd);

treeView.WndProc(ref msg);

// 1. A valid (non-null) brush handle must be returned.
Assert.NotEqual(IntPtr.Zero, (nint)msg.ResultInternal);

// 2. DC text color must match the ForeColor we set on the control.
Color actualTextColor = PInvoke.GetTextColor(hdc);
Assert.Equal(
ColorTranslator.ToWin32(expectedForeColor),
ColorTranslator.ToWin32(actualTextColor));

// 3. DC background color must match the BackColor we set on the control.
Color actualBkColor = PInvoke.GetBkColor(hdc);
Assert.Equal(
ColorTranslator.ToWin32(expectedBackColor),
ColorTranslator.ToWin32(actualBkColor));

treeView.Nodes[0].EndEdit(cancel: true);
}

private class SubTreeView : TreeView
{
public new bool CanEnableIme => base.CanEnableIme;
Expand Down Expand Up @@ -7674,5 +7730,7 @@ private class SubTreeView : TreeView
public new void OnNodeMouseHover(TreeNodeMouseHoverEventArgs e) => base.OnNodeMouseHover(e);

public new void OnRightToLeftLayoutChanged(EventArgs e) => base.OnRightToLeftLayoutChanged(e);

public new void WndProc(ref Message m) => base.WndProc(ref m);
}
}
Loading