In my application, I missed the WM_DRAWITEM at some special moment. So I have to send it manually when WM_WINDOWPOSCHANGING.
But I found that in derived WndProc, I only got WM_REFLECT + WM_DRAWITEMat normal moment. Then what should I send? With WM_REFLECT or without?
0x202b = WM_RELFECT + WM_DRAWITEM
0x2b = WM_DRAWITEM.
However, in my test, if sent 0x2b, looked like this msg didn't take effect. if sent 0x202b, I got damned OutOfMemory exception.
Here is my code,
if (message.Msg == WM_WINDOWPOSCHANGE) // WM_WINDOWPOSCHANGING
{
base.WndProc(ref message);
for (int idx = 0; idx < this.Items.Count; idx++)
{
DRAWITEMSTRUCT iteminfo = new DRAWITEMSTRUCT();
iteminfo.CtlType = DRAWITEMCONST.ODT_LISTBOX;
iteminfo.CtlID = (uint)this.Handle.ToInt32(); // ???
iteminfo.itemID = (uint)idx;
iteminfo.itemAction = DRAWITEMCONST.ODA_DRAWENTIRE;
iteminfo.hwndItem = this.Handle;
iteminfo.hDC = this.CreateGraphics().GetHdc();
iteminfo.itemState = DRAWITEMCONST.ODS_NOFOCUSRECT | DRAWITEMCONST.ODS_NOACCEL;
iteminfo.rcItem = new RECT();
GCHandle gch = GCHandle.Alloc(this.Items[idx].ToString());
iteminfo.itemData = GCHandle.ToIntPtr(gch);
// got selected item
if (this.SelectedIndices.Contains(idx))
{
iteminfo.itemState |= DRAWITEMCONST.ODS_FOCUS | DRAWITEMCONST.ODS_SELECTED;
Rectangle rect = this.GetItemRectangle(idx);
iteminfo.rcItem.left = rect.Left;
iteminfo.rcItem.top = rect.Top;
iteminfo.rcItem.right = rect.Right;
iteminfo.rcItem.bottom = rect.Bottom;
}
GCHandle gch2 = GCHandle.Alloc(iteminfo);
Win32NativeMethods.SendMessage(this.Handle, 0x202b, this.Handle, GCHandle.ToIntPtr(gch2));
Debug.WriteLine("Send a WM_DRAWITEM");
//gch.Free(); // only when test
//gch2.Free();
}
}