OSDN Git Service

DetailsListView の再描画範囲を制御する処理を元に戻した
authorspx <spx268@gmail.com>
Wed, 19 Jun 2013 12:25:44 +0000 (21:25 +0900)
committerspx <spx268@gmail.com>
Wed, 19 Jun 2013 12:31:54 +0000 (21:31 +0900)
1.0.9 相当

OpenTween/DetailsListView.cs
OpenTween/Tween.cs
OpenTween/Win32Api.cs

index 6e9957e..5510961 100644 (file)
@@ -38,6 +38,7 @@ namespace OpenTween.OpenTweenCustomControl
 {
     public sealed class DetailsListView : ListView
     {
+        private Rectangle changeBounds;
         private EventHandlerList _handlers = new EventHandlerList();
 
         public event EventHandler VScrolled;
@@ -122,30 +123,89 @@ namespace OpenTween.OpenTweenCustomControl
 
         public void ChangeSubItemBackColor(int itemIndex, int subitemIndex, Color backColor)
         {
-            this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor;
+            var item = this.Items[itemIndex];
+            item.SubItems[subitemIndex].BackColor = backColor;
+            SetUpdateBounds(item, subitemIndex);
+            this.Update();
+            this.changeBounds = Rectangle.Empty;
         }
 
         public void ChangeSubItemForeColor(int itemIndex, int subitemIndex, Color foreColor)
         {
-            this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
+            var item = this.Items[itemIndex];
+            item.SubItems[subitemIndex].ForeColor = foreColor;
+            SetUpdateBounds(item, subitemIndex);
+            this.Update();
+            this.changeBounds = Rectangle.Empty;
         }
 
         public void ChangeSubItemFont(int itemIndex, int subitemIndex, Font fnt)
         {
-            this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+            var item = this.Items[itemIndex];
+            item.SubItems[subitemIndex].Font = fnt;
+            SetUpdateBounds(item, subitemIndex);
+            this.Update();
+            this.changeBounds = Rectangle.Empty;
         }
 
         public void ChangeSubItemFontAndColor(int itemIndex, int subitemIndex, Color foreColor, Font fnt)
         {
-            this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
-            this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+            var item = this.Items[itemIndex];
+            var subItem = item.SubItems[subitemIndex];
+            subItem.ForeColor = foreColor;
+            subItem.Font = fnt;
+            SetUpdateBounds(item, subitemIndex);
+            this.Update();
+            this.changeBounds = Rectangle.Empty;
         }
 
         public void ChangeSubItemStyles(int itemIndex, int subitemIndex, Color backColor, Color foreColor, Font fnt)
         {
-            this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor;
-            this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
-            this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+            var item = this.Items[itemIndex];
+            var subItem = item.SubItems[subitemIndex];
+            subItem.BackColor = backColor;
+            subItem.ForeColor = foreColor;
+            subItem.Font = fnt;
+            SetUpdateBounds(item, subitemIndex);
+            this.Update();
+            this.changeBounds = Rectangle.Empty;
+        }
+
+        private void SetUpdateBounds(ListViewItem item, int subItemIndex)
+        {
+            try
+            {
+                if (subItemIndex > this.Columns.Count)
+                {
+                    throw new ArgumentOutOfRangeException("subItemIndex");
+                }
+                if (item.UseItemStyleForSubItems)
+                {
+                    this.changeBounds = item.Bounds;
+                }
+                else
+                {
+                    this.changeBounds = this.GetSubItemBounds(item, subItemIndex);
+                }
+            }
+            catch (ArgumentException)
+            {
+                //タイミングによりBoundsプロパティが取れない?
+                this.changeBounds = Rectangle.Empty;
+            }
+        }
+
+        private Rectangle GetSubItemBounds(ListViewItem item, int subitemIndex)
+        {
+            if (subitemIndex == 0 && this.Columns.Count > 0)
+            {
+                Rectangle col0 = item.Bounds;
+                return new Rectangle(col0.Left, col0.Top, item.SubItems[1].Bounds.X + 1, col0.Height);
+            }
+            else
+            {
+                return item.SubItems[subitemIndex].Bounds;
+            }
         }
 
         [StructLayout(LayoutKind.Sequential)]
@@ -189,6 +249,8 @@ namespace OpenTween.OpenTweenCustomControl
         [DebuggerStepThrough()]
         protected override void WndProc(ref Message m)
         {
+            const int WM_ERASEBKGND = 0x14;
+            const int WM_PAINT = 0xF;
             const int WM_MOUSEWHEEL = 0x20A;
             const int WM_MOUSEHWHEEL = 0x20E;
             const int WM_HSCROLL = 0x114;
@@ -203,6 +265,18 @@ namespace OpenTween.OpenTweenCustomControl
 
             switch (m.Msg)
             {
+                case WM_ERASEBKGND:
+                    if (this.changeBounds != Rectangle.Empty)
+                        m.Msg = 0;
+                    break;
+                case WM_PAINT:
+                    if (this.changeBounds != Rectangle.Empty)
+                    {
+                        Win32Api.ValidateRect(this.Handle, IntPtr.Zero);
+                        this.Invalidate(this.changeBounds);
+                        this.changeBounds = Rectangle.Empty;
+                    }
+                    break;
                 case WM_HSCROLL:
                     if (HScrolled != null)
                         HScrolled(this, EventArgs.Empty);
index f4dd165..729b9f6 100644 (file)
@@ -2055,7 +2055,8 @@ namespace OpenTween
 
             if (_post == null) return;
 
-            var itemColorTuple = new Tuple<ListViewItem, Color>[] { };
+            var itemColors = new Color[] { };
+            int itemIndex = -1;
 
             this.itemCacheLock.EnterReadLock();
             try
@@ -2064,17 +2065,20 @@ namespace OpenTween
 
                 var query = 
                     from i in Enumerable.Range(0, this._itemCache.Length)
-                    select new Tuple<ListViewItem, Color>(this._itemCache[i], this.JudgeColor(_post, this._postCache[i]));
+                    select this.JudgeColor(_post, this._postCache[i]);
                 
-                itemColorTuple = query.ToArray();
+                itemColors = query.ToArray();
+                itemIndex = _itemCacheIndex;
             }
             finally { this.itemCacheLock.ExitReadLock(); }
 
-            foreach (var tuple in itemColorTuple)
+            if (itemIndex < 0) return;
+
+            foreach (var backColor in itemColors)
             {
                 // この処理中に MyList_CacheVirtualItems が呼ばれることがあるため、
                 // 同一スレッド内での二重ロックを避けるためにロックの外で実行する必要がある
-                tuple.Item1.SubItems[0].BackColor = tuple.Item2;
+                _curList.ChangeItemBackColor(itemIndex++, backColor);
             }
         }
 
index 71f2528..3578dd9 100644 (file)
@@ -546,6 +546,11 @@ namespace OpenTween
         private const Int32 FLASHW_TIMERNOFG = 0xC;
         #endregion
 
+        [DllImport("user32.dll")]
+        public static extern bool ValidateRect(
+            IntPtr hwnd,
+            IntPtr rect);
+
         #region "スクリーンセーバー起動中か判定"
         [DllImport("user32", CharSet = CharSet.Auto)]
         private static extern int SystemParametersInfo(