/// <summary>
        /// アイテムの内容を変更します。
        /// LVN_ITEMCHANGING, LVN_ITEMCHANGEDの通知が発生します。
        /// </summary>
        /// <param name="handle">ウィンドウハンドル。</param>
        /// <param name="item">アイテム。</param>
        private static void EmulateChangeItemInTarget(IntPtr handle, LVITEM item)
        {
            NativeMethods.SetFocus(handle);
            bool isUni = NativeMethods.IsWindowUnicode(handle);
            int LVM_SETITEM = isUni ? LVM_SETITEMW : LVM_SETITEMA;

            item._core.pszText = isUni ? Marshal.StringToCoTaskMemUni(item.pszText) :
                                            Marshal.StringToCoTaskMemAnsi(item.pszText);
            try
            {
                NativeMethods.SendMessage(handle, LVM_SETITEM, IntPtr.Zero, ref item._core);
            }
            finally
            {
                Marshal.FreeCoTaskMem(item._core.pszText);
            }
        }
 /// <summary>
 /// アイテムを取得します。
 /// </summary>
 /// <param name="isUni">ユニコードであるか。</param>
 /// <param name="message">メッセージ。</param>
 /// <param name="wParam">WPARAM。</param>
 /// <param name="item">アイテム。</param>
 /// <returns>成否。</returns>
 private IntPtr GetItemCore(bool isUni, int message, IntPtr wParam, LVITEM item)
 {
     AppVar inTarget = App.Dim(item);
     IntPtr ret = (IntPtr)App[GetType(), "GetItemCoreInTarget"](Handle, isUni, message, wParam, inTarget).Core;
     LVITEM getData = (LVITEM)inTarget.Core;
     item._core = getData._core;
     item.pszText = getData.pszText;
     return ret;
 }
        /// <summary>
        /// アイテムを取得します。
        /// </summary>
        /// <param name="handle">ウィンドウハンドル。</param>
        /// <param name="isUni">ユニコードであるか。</param>
        /// <param name="message">メッセージ。</param>
        /// <param name="wParam">WPARAM。</param>
        /// <param name="item">アイテム。</param>
        /// <returns>成否。</returns>
        private static IntPtr GetItemCoreInTarget(IntPtr handle, bool isUni, int message, IntPtr wParam, LVITEM item)
        {
            //文字列取得の場合バッファを確保する。
            if (((item.mask & LVIF.TEXT) == LVIF.TEXT) ||
                 (message == LVM_GETITEMTEXTW) ||
                 (message == LVM_GETITEMTEXTA))
            {
                item._core.cchTextMax = 256;
            }

            while (true)
            {
                if (0 < item._core.cchTextMax)
                {
                    item._core.pszText = Marshal.AllocCoTaskMem((item._core.cchTextMax + 1) * 8);
                }
                IntPtr ret = IntPtr.Zero;
                try
                {
                    ret = NativeMethods.SendMessage(handle, message, wParam, ref item._core);
                    if (item._core.pszText == IntPtr.Zero)
                    {
                        return ret;
                    }
                    item.pszText = isUni ? Marshal.PtrToStringUni(item._core.pszText) :
                                        Marshal.PtrToStringAnsi(item._core.pszText);

                    //文字列がサイズに収まっていれば終了。
                    if (item.pszText.Length < item._core.cchTextMax - 1)
                    {
                        return ret;
                    }

                    //リトライ。
                    item._core.cchTextMax *= 2;
                }
                finally
                {
                    if (item._core.pszText != IntPtr.Zero)
                    {
                        Marshal.FreeCoTaskMem(item._core.pszText);
                    }
                }
            }
        }
        /// <summary>
        /// Changes the contents of an item.
        /// Causes a notice according to the changes.
        /// Executes asynchronously. 
        /// </summary>
        /// <param name="item">Item.</param>
        /// <param name="async">Asynchronous execution object.</param>
#else
        /// <summary>
        /// アイテムの内容を変更します。
        /// 変更内容に応じて通知が発生します。
        /// 非同期で実行します。
        /// </summary>
        /// <param name="item">アイテム。</param>
        /// <param name="async">非同期実行オブジェクト。</param>
#endif
        public void EmulateChangeItem(LVITEM item, Async async)
        {
            App[GetType(), "EmulateChangeItemInTarget", async](Handle, item);
        }
 /// <summary>
 /// 指定のテキストのアイテムを検索します。
 /// </summary>
 /// <param name="handle">ウィンドウハンドル。</param>
 /// <param name="findStart">検索開始インデックス。</param>
 /// <param name="targetSubItemIndex">検索対象のサブアイテムインデックス。</param>
 /// <param name="text">テキスト。</param>
 /// <returns>アイテムインデックス。未発見時は-1が返ります。</returns>
 private static int FindItemInTarget(IntPtr handle, int findStart, int targetSubItemIndex, string text)
 {
     bool isUni = NativeMethods.IsWindowUnicode(handle);
     int LVM_GETITEMTEXT = isUni ? LVM_GETITEMTEXTW : LVM_GETITEMTEXTA;
     int count = (int)NativeMethods.SendMessage(handle, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero);
     for (int i = findStart; i < count; i++)
     {
         LVITEM lvi = new LVITEM();
         lvi.iSubItem = targetSubItemIndex;
         GetItemCoreInTarget(handle, isUni, LVM_GETITEMTEXT, new IntPtr(i), lvi);
         if (lvi.pszText == text)
         {
             return i;
         }
     }
     return -1;
 }
        /// <summary>
        /// Returns item data.
        /// </summary>
        /// <param name="itemIndex">Index of the item.</param>
        /// <returns>Item data.</returns>
#else
        /// <summary>
        /// アイテムデータを取得します。
        /// </summary>
        /// <param name="itemIndex">アイテムインデックス。</param>
        /// <returns>アイテムデータ。</returns>
#endif
        public IntPtr GetItemData(int itemIndex)
        {
            LVITEM lvi = new LVITEM();
            lvi.iItem = itemIndex;
            lvi.mask = LVIF.PARAM;
            GetItem(lvi);
            return lvi.lParam;
        }
        /// <summary>
        /// Changes the contents of an item.
        /// Causes a notice according to the changes.
        /// </summary>
        /// <param name="item">Item.</param>
#else
        /// <summary>
        /// アイテムの内容を変更します。
        /// 変更内容に応じて通知が発生します。
        /// </summary>
        /// <param name="item">アイテム。</param>
#endif
        public void EmulateChangeItem(LVITEM item)
        {
            App[GetType(), "EmulateChangeItemInTarget"](Handle, item);
        }
        /// <summary>
        /// Gets the text for an item.
        /// </summary>
        /// <param name="itemIndex">Index of the item.</param>
        /// <param name="subItemIndex">Sub-item index.</param>
        /// <returns>Item text.</returns>
#else
        /// <summary>
        /// アイテム文字列を取得します。
        /// </summary>
        /// <param name="itemIndex">アイテムインデックス。</param>
        /// <param name="subItemIndex">サブアイテムインデックス。</param>
        /// <returns>アイテム文字列。</returns>
#endif
        public string GetItemText(int itemIndex, int subItemIndex)
        {
            bool isUni = (bool)App[typeof(NativeMethods), "IsWindowUnicode"](Handle).Core;
            int LVM_GETITEMTEXT = isUni ? LVM_GETITEMTEXTW : LVM_GETITEMTEXTA;
            LVITEM lvi = new LVITEM();
            lvi.iSubItem = subItemIndex;
            GetItemCore(isUni, LVM_GETITEMTEXT, new IntPtr(itemIndex), lvi);
            return lvi.pszText;
        }
        /// <summary>
        /// Obtains an item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>Success or failure.</returns>
#else
        /// <summary>
        /// アイテムを取得します。
        /// </summary>
        /// <param name="item">アイテム。</param>
        /// <returns>成否。</returns>
#endif
        public bool GetItem(LVITEM item)
        {
            bool isUni = (bool)App[typeof(NativeMethods), "IsWindowUnicode"](Handle).Core;
            int LVM_GETITEM = isUni ? LVM_GETITEMW : LVM_GETITEMA;
            return NativeDataUtility.ToBool(GetItemCore(isUni, LVM_GETITEM, IntPtr.Zero, item));
        }
 public void TestEmulateChangeItemEventAsync()
 {
     NativeListControl list = new NativeListControl(testDlg.IdentifyFromDialogId(1038));
     LVITEM item = new LVITEM();
     item.iItem = 1;
     item.mask = LVIF.TEXT;
     item.pszText = "zzz";
     Async async = new Async();
     list.EmulateChangeItem(item, async);
     Assert.IsTrue(0 < MessageBoxUtility.CloseAll(testDlg, async));
 }
 public void TestEmulateChangeItemEvent()
 {
     NativeListControl list = new NativeListControl(testDlg.IdentifyFromDialogId(1037));
     Assert.IsTrue(EventChecker.IsSameTestEvent(testDlg,
         delegate
         {
             LVITEM item = new LVITEM();
             item.iItem = 1;
             item.mask = LVIF.TEXT;
             item.pszText = "zzz";
             list.EmulateChangeItem(item); 
         },
         new CodeInfo(1037, NativeMethods.WM_NOTIFY, LVN_ITEMCHANGING),
         new CodeInfo(1037, NativeMethods.WM_NOTIFY, LVN_ITEMCHANGED)
     ));
 }
        public void TestSetGetItem()
        {
            NativeListControl list = new NativeListControl(testDlg.IdentifyFromDialogId(1037));

            LVITEM setData = new LVITEM();
            LVITEM getData = new LVITEM();
            foreach (LVIF element in (LVIF[])Enum.GetValues(typeof(LVIF)))
            {
                setData.mask |= element;
                getData.mask |= element;
            }
            foreach (LVIS element in (LVIS[])Enum.GetValues(typeof(LVIS)))
            {
                setData.stateMask |= element;
                getData.stateMask |= element;
            }

            //アイテムの変更
            setData.iItem = 2;
            setData.iSubItem = 0;
            setData.state = LVIS.CUT;
            setData.pszText = "abc";
            setData.iImage = 2;
            setData.lParam = new IntPtr(3);
            list.EmulateChangeItem(setData);

            //変更結果の確認
            getData.iItem = 2;
            getData.iSubItem = 0;
            list.GetItem(getData);
            Assert.AreEqual(setData.iItem, getData.iItem);
            Assert.AreEqual(setData.iSubItem, getData.iSubItem);
            Assert.AreEqual(setData.state, getData.state);
            Assert.AreEqual(setData.pszText, getData.pszText);
            Assert.AreEqual(setData.iImage, getData.iImage);
            Assert.AreEqual(setData.lParam, getData.lParam);

            //非同期でも同様の効果があることを確認。
            Async a = new Async();
            setData.pszText = "efg";
            list.EmulateChangeItem(setData, a);
            while (!a.IsCompleted)
            {
                Thread.Sleep(10);
            }
            list.GetItem(getData);
            Assert.AreEqual(setData.pszText, getData.pszText);
        }