/[RomCheater]/trunk/RomCheater/Docking/FloatingMemorySearcher.cs
ViewVC logotype

Diff of /trunk/RomCheater/Docking/FloatingMemorySearcher.cs

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/RomCheater/Docking/FloatingMemorySearcher.cs	2012/06/02 18:31:40	229
+++ trunk/RomCheater/Docking/FloatingMemorySearcher.cs	2012/06/02 19:12:20	230
@@ -12,6 +12,9 @@
 using System.Diagnostics;
 using RomCheater.Docking.MemorySearch;
 using libWin32.Win32.Threading;
+using System.Threading;
+using RomCheater.Logging;
+using System.IO;
 
 namespace RomCheater.Docking
 {
@@ -42,8 +45,49 @@
             radio_8bits.Checked = true;
             radiocompare_equal.Checked = true;
             radio_oldvalue.Checked = true;
+            chkRefreshResults.Checked = true;
+        }
+        public enum eListViewResults
+        {
+            SEARCH_RESULTS_LIST = 0x3000,
+            PATCH_RESULTS_LIST = 0x3001,
+            UKNOWN_RESULTS_LIST = 0x3001
+        }
+        static int col_Found_Address = 0;
+        static int col_Found_Value = 1;
+        static int col_Found_Frozen = 2;
+        static int col_Added_Address = 0;
+        static int col_Added_Value = 1;
+        static int col_Added_Frozen = 2;
+        List<ListViewItem> ResultItems = new List<ListViewItem>();
+        List<ListViewItem> AddedItems = new List<ListViewItem>();
+        private bool _PatchedValue_NeedsUpdate;
+        bool PatchedValue_NeedsUpdate
+        {
+            get { if (_PatchedValue_NeedsUpdate) this.ThawResultsUpdate(); return _PatchedValue_NeedsUpdate; }
+            set { _PatchedValue_NeedsUpdate = value; if (value) this.ThawResultsUpdate(); }
+        }
+        private delegate ListViewItem ThreadSafe_GetResultItem(int index, int lv_type);
+        private ListViewItem GetResultItem(int index, int lv_type)
+        {
+            try
+            {
+                AddressValuePairList lv = null;
+                switch (lv_type)
+                {
+                    case (int)eListViewResults.SEARCH_RESULTS_LIST: lv = lstResults; break;
+                    case (int)eListViewResults.PATCH_RESULTS_LIST: lv = lstPatchList; break;
+                    default: throw new IndexOutOfRangeException("Detected: " + Enum.GetName(typeof(eListViewResults), eListViewResults.UKNOWN_RESULTS_LIST) + " with value: " + lv_type.ToString("x4"));
+                }
+                ListViewItem item = new ListViewItem();
+                item = (ListViewItem)lv.Items[index].Clone();
+                return item;
+            }
+            catch (Exception)
+            {
+                return null;
+            }
         }
-
         private void radiocompare_equal_CheckedChanged(object sender, EventArgs e)
         {
             //if (!radiocompare_between.Checked && !radiocompare_notbetween.Checked)
@@ -217,15 +261,227 @@
                 ResultsUpdateWorkerThread.RunWorkerAsync();
             }
         }
-
+        private bool ShouldUpdateResults()
+        {
+            if (this.AcceptedProcess == null) return false;
+            if (SearchWorkerThread.IsBusy) return false;
+            //if (JokerSearchWorker.IsBusy) return false;
+            if (this.IsResultsUpdateFrozen) return false;
+            if (mnuAddedResults.Visible) return false;
+            if (mnuResults.Visible) return false;
+            if (Process.GetProcessById(this.AcceptedProcess.Id) == null) return false;
+            if (lstResults.Items.Count > 0) return true;
+            if (lstPatchList.Items.Count > 0) return true;
+            return false;
+        }
         private void ResultsUpdateWorkerThread_DoWork(object sender, DoWorkEventArgs e)
         {
+            Thread.Sleep(250); // keep thread from blocking
+            if (!this.ShouldUpdateResults()) return;
+            ////if (SearchArgs == null) return;
+            ////if (this.IsResultsUpdateFrozen) return;
+            ////// put thread to sleep for 500ms
+            ////System.Threading.Thread.Sleep(500);
+            //PCSX2MemoryProvider provider = new PCSX2MemoryProvider(this.SearchPCSX2ProcessPID, resultslog);
+            //byte[] buffered_mem = provider.GetMemory();
+            //MemoryStream ms = new MemoryStream(buffered_mem);
+            //BinaryReader r_ms = new BinaryReader(ms);
+
+            #region Update Results List
+            ResultItems = new List<ListViewItem>();
+            //r_ms.BaseStream.Seek(0, SeekOrigin.Begin);
+            for (int i = 0; i < lstResults.Items.Count; i++)
+            {
+                if (this.lstResults.InvokeRequired)
+                {
+                    ThreadSafe_GetResultItem _get_item = new ThreadSafe_GetResultItem(GetResultItem);
+                    object item = this.lstResults.Invoke(_get_item, new object[] { i, (int)eListViewResults.SEARCH_RESULTS_LIST });
+                    if (item != null)
+                        ResultItems.Add((ListViewItem)item);
+                }
+                else
+                {
+                    ResultItems.Add(lstResults.Items[i]);
+                }
 
+            }
+            for (int i = 0; i < ResultItems.Count; i++)
+            {
+                if (ResultsUpdateWorkerThread.CancellationPending == true)
+                {
+                    e.Cancel = true;
+                    return;
+                }
+                uint Address = 0;
+                ResultDataType _result = (ResultDataType)ResultItems[i].Tag;
+                
+                Address = Convert.ToUInt32(ResultItems[i].SubItems[col_Found_Address].Text, 16);
+                //r_ms.BaseStream.Seek(Address, SeekOrigin.Begin);
+                Sojaner.MemoryScanner.ProcessMemoryReader reader = new Sojaner.MemoryScanner.ProcessMemoryReader();
+                reader.ReadProcess = Process.GetProcessById(this.AcceptedProcess.Id);
+                if (reader.ReadProcess == null) { logger.Error.WriteLine("Could not attach to process: {0}", this.AcceptedProcess.Id); return; }
+                reader.OpenProcess();
+                int bytesReadSize;
+                byte[] data;
+                uint bytesToRead = 0;
+                switch (_result.ValueType)
+                {
+                    case SearchDataTypes._8bits:
+                        bytesToRead = 1;
+                        break;
+                    case SearchDataTypes._16bits:
+                        bytesToRead = 2;
+                        break;
+                    case SearchDataTypes._32bits:
+                        bytesToRead = 4;
+                        break;
+                    case SearchDataTypes._64bits:
+                        bytesToRead = 8;
+                        break;
+                }
+                reader.ReadProcessMemory(Address, bytesToRead, out bytesReadSize, out data);
+                MemoryStream ms = new MemoryStream(data);
+                BinaryReader r_ms = new BinaryReader(ms);
+                switch (_result.ValueType)
+                {
+                    case SearchDataTypes._8bits:
+                        if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x2}", r_ms.ReadByte()); }
+                        else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x2}", r_ms.ReadSByte()); }
+                        break;
+                    case SearchDataTypes._16bits:
+                        if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x4}", r_ms.ReadUInt16()); }
+                        else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x4}", r_ms.ReadInt16()); }
+                        break;
+                    case SearchDataTypes._32bits:
+                        if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x8}", r_ms.ReadUInt32()); }
+                        else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x8}", r_ms.ReadInt32()); }
+                        break;
+                    case SearchDataTypes._64bits:
+                        if (_result.IsUnsigned) { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x16}", r_ms.ReadUInt64()); }
+                        else { ResultItems[i].SubItems[col_Found_Value].Text = string.Format("0x{0:x16}", r_ms.ReadInt64()); }
+                        break;
+                }
+                r_ms.Close();
+                reader.CloseHandle();
+                Application.DoEvents();
+            }
+            #endregion
+
+            #region Update Added Results List
+            AddedItems = new List<ListViewItem>();
+            //r_ms.BaseStream.Seek(0, SeekOrigin.Begin);
+            for (int i = 0; i < lstPatchList.Items.Count; i++)
+            {
+                if (this.lstResults.InvokeRequired)
+                {
+                    ThreadSafe_GetResultItem _get_item = new ThreadSafe_GetResultItem(GetResultItem);
+                    object item = this.lstResults.Invoke(_get_item, new object[] { i, (int)eListViewResults.PATCH_RESULTS_LIST });
+                    if (item != null)
+                        AddedItems.Add((ListViewItem)item);
+                }
+                else
+                {
+                    AddedItems.Add(lstPatchList.Items[i]);
+                }
+
+            }
+            for (int i = 0; i < AddedItems.Count; i++)
+            {
+                if (ResultsUpdateWorkerThread.CancellationPending == true)
+                {
+                    e.Cancel = true;
+                    return;
+                }
+                uint Address = 0;
+                ResultDataType _result = (ResultDataType)AddedItems[i].Tag;
+                Address = Convert.ToUInt32(AddedItems[i].SubItems[col_Added_Address].Text, 16);
+                Sojaner.MemoryScanner.ProcessMemoryReader reader = new Sojaner.MemoryScanner.ProcessMemoryReader();
+                reader.ReadProcess = Process.GetProcessById(this.AcceptedProcess.Id);
+                if (reader.ReadProcess == null) { logger.Error.WriteLine("Could not attach to process: {0}", this.AcceptedProcess.Id); return; }
+                reader.OpenProcess();
+                int bytesReadSize;
+                byte[] data;
+                uint bytesToRead = 0;
+                switch (_result.ValueType)
+                {
+                    case SearchDataTypes._8bits:
+                        bytesToRead = 1;
+                        break;
+                    case SearchDataTypes._16bits:
+                        bytesToRead = 2;
+                        break;
+                    case SearchDataTypes._32bits:
+                        bytesToRead = 4;
+                        break;
+                    case SearchDataTypes._64bits:
+                        bytesToRead = 8;
+                        break;
+                }
+                reader.ReadProcessMemory(Address, bytesToRead, out bytesReadSize, out data);
+                MemoryStream ms = new MemoryStream(data);
+                BinaryReader r_ms = new BinaryReader(ms);
+                switch (_result.ValueType)
+                {
+                    case SearchDataTypes._8bits:
+                        if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x2}", r_ms.ReadByte()); }
+                        else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x2}", r_ms.ReadSByte()); }
+                        break;
+                    case SearchDataTypes._16bits:
+                        if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x4}", r_ms.ReadUInt16()); }
+                        else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x4}", r_ms.ReadInt16()); }
+                        break;
+                    case SearchDataTypes._32bits:
+                        if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x8}", r_ms.ReadUInt32()); }
+                        else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x8}", r_ms.ReadInt32()); }
+                        break;
+                    case SearchDataTypes._64bits:
+                        if (_result.IsUnsigned) { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x16}", r_ms.ReadUInt64()); }
+                        else { AddedItems[i].SubItems[col_Added_Value].Text = string.Format("0x{0:x16}", r_ms.ReadInt64()); }
+                        break;
+                }
+                r_ms.Close();
+                reader.CloseHandle();
+                Application.DoEvents();
+            }
+            #endregion
+
+            
         }
 
         private void ResultsUpdateWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
         {
+            try
+            {
+                //if ((lstResults.SelectedItems.Count > 0) && !PatchedValue_NeedsUpdate ) return;
+                //if ((lstPatchList.SelectedItems.Count > 0) && !PatchedValue_NeedsUpdate) return;
+                if (!this.ShouldUpdateResults()) return;
+                if (ResultItems.Count > 0)
+                {
+                    //lstResults.Items.Clear();
+                    //lstResults.Items.AddRange(ResultItems.ToArray());
+
+                    for (int i = 0; i < ResultItems.Count; i++)
+                    {
+                        lstResults.Items[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text =
+                            ResultItems[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text;
+                    }
+
+                }
+                if (AddedItems.Count > 0)
+                {
+                    //lstPatchList.Items.Clear();
+                    //lstPatchList.Items.AddRange(AddedItems.ToArray());
 
+                    for (int i = 0; i < AddedItems.Count; i++)
+                    {
+                        lstPatchList.Items[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text =
+                            AddedItems[i].SubItems[new AVPColumnText(AVPColumnType.VALUE).ColumnIndex].Text;
+                    }
+
+                }
+                PatchedValue_NeedsUpdate = false;
+            }
+            catch { }
         }
 
         private void btnImportFile_Click(object sender, EventArgs e)
@@ -389,5 +645,278 @@
             ResultItem item = new ResultItem(state.Address, state.Value, state.Frozen, state.ValueType, state.IsUnsigned);
             this.AddToPatchList(item);
         }
+
+        private void mnuItemAddToPatchList_Click(object sender, EventArgs e)
+        {
+            if (!(lstResults.SelectedItems.Count > 0)) return;
+            //if (SearchArgs == null) return;
+
+            try
+            {
+                for (int i = 0; i < lstResults.SelectedIndices.Count; i++)
+                {
+                    //ResultDataType result = (ResultDataType)lstResults.Items[selected_index].Tag;
+                    ListViewItem item = lstResults.Items[lstResults.SelectedIndices[i]];
+                    this.AddToPatchList(item);
+                }
+            }
+            catch (Exception ex)
+            {
+                logger.Error.WriteLine(ex.ToString());
+            }
+        }
+
+        private void mnuItemRemoveResult_Click(object sender, EventArgs e)
+        {
+            if (!(lstPatchList.SelectedItems.Count > 0)) return;
+            //if (SearchArgs == null) return;
+            try
+            {
+                this.FreezeResultsUpdate();
+                for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++)
+                {
+                    //lstPatchList.ThawItem(lstPatchList.SelectedIndices[i]);
+                    lstPatchList.Items[lstPatchList.SelectedIndices[i]].Remove();
+                }
+                this.ThawResultsUpdate();
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+        private void PatchRange(bool SingleEntry)
+        {
+            //if (SearchArgs == null) return;
+            #region Patch Selected Address
+            // stop ResultsUpdate Thread
+            ResultsUpdateWorkerThread.CancelAsync();
+
+            List<ResultDataType> patch_list = new List<ResultDataType>();
+            List<int> SelectedIndexes = new List<int>();
+
+            if (SingleEntry)
+            {
+                SelectedIndexes.Add(lstPatchList.SelectedIndices[0]);
+            }
+            else
+            {
+                foreach (int index in lstPatchList.SelectedIndices)
+                {
+                    SelectedIndexes.Add(index);
+                }
+            }
+            //PCSX2MemoryProvider provider = new PCSX2MemoryProvider(this.SearchPCSX2ProcessPID, resultslog);
+            foreach (int index in SelectedIndexes)
+            {
+                if (SingleEntry)
+                {
+                    SearchPatcher patcher = null;
+                    uint Address = 0;
+                    ListViewItem item = lstPatchList.Items[index];
+                    ResultDataType _result = (ResultDataType)item.Tag;
+                    Address = Convert.ToUInt32(item.SubItems[col_Found_Address].Text, 16);
+                    switch (_result.ValueType)
+                    {
+                        case SearchDataTypes._8bits:
+                            if (_result.IsUnsigned)
+                            {
+                                byte value = Convert.ToByte(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            else
+                            {
+                                sbyte value = Convert.ToSByte(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            break;
+                        case SearchDataTypes._16bits:
+                            if (_result.IsUnsigned)
+                            {
+                                ushort value = Convert.ToUInt16(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            else
+                            {
+                                short value = Convert.ToInt16(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            break;
+                        case SearchDataTypes._32bits:
+                            if (_result.IsUnsigned)
+                            {
+                                uint value = Convert.ToUInt32(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            else
+                            {
+                                int value = Convert.ToInt32(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            break;
+                        case SearchDataTypes._64bits:
+                            if (_result.IsUnsigned)
+                            {
+                                ulong value = Convert.ToUInt32(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            else
+                            {
+                                long value = Convert.ToInt32(item.SubItems[col_Found_Value].Text, 16);
+                                patcher = new SearchPatcher(this.AcceptedProcess.Id, Address, value);
+                                timer_update_results.Enabled = false;
+                                patcher.ShowDialog();
+                                timer_update_results.Enabled = true;
+                                PatchedValue_NeedsUpdate = true;
+                                if (!chkRefreshResults.Checked && !ResultsUpdateWorkerThread.IsBusy)
+                                    ResultsUpdateWorkerThread.RunWorkerAsync();
+                            }
+                            break;
+                    }
+                }
+                else
+                {
+
+                    ListViewItem item = lstPatchList.Items[index];
+                    ResultDataType _result = (ResultDataType)item.Tag;
+                    patch_list.Add(_result);
+                }
+            }
+
+            if (patch_list.Count > 0)
+            {
+                SearchRangePatcher rangePatcher = new SearchRangePatcher(this.AcceptedProcess.Id, patch_list);
+                rangePatcher.ShowDialog();
+            }
+
+            #endregion
+        }
+        private void mnuItemPatchSelectedEntry_Click(object sender, EventArgs e)
+        {
+            if (!(lstPatchList.SelectedItems.Count == 1)) return;
+            PatchRange(true);
+        }
+
+        private void mnuItemPatchSelectedRange_Click(object sender, EventArgs e)
+        {
+            if (!(lstPatchList.SelectedItems.Count >= 1)) return;
+            PatchRange(false);
+        }
+
+        private void mnuItemFreezeSelectedPatches_Click(object sender, EventArgs e)
+        {
+            if (!(lstPatchList.SelectedItems.Count > 0)) return;
+            //if (SearchArgs == null) return;
+            try
+            {
+                lstPatchList.ProcessID = this.AcceptedProcess.Id;
+                this.FreezeResultsUpdate();
+                for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++)
+                {
+                    lstPatchList.FreezeItem(lstPatchList.SelectedIndices[i]);
+                }
+                // force thaw and update
+                this.ThawResultsUpdate();
+                this.Update();
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+
+        private void mnuItemThawSelectedPatches_Click(object sender, EventArgs e)
+        {
+            if (!(lstPatchList.SelectedItems.Count > 0)) return;
+            //if (SearchArgs == null) return;
+            try
+            {
+                lstPatchList.ProcessID = this.AcceptedProcess.Id;
+                this.FreezeResultsUpdate();
+                for (int i = 0; i < lstPatchList.SelectedIndices.Count; i++)
+                {
+                    lstPatchList.ThawItem(lstPatchList.SelectedIndices[i]);
+                }
+                // force thaw and update
+                this.ThawResultsUpdate();
+                this.Update();
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine(ex.ToString());
+            }
+        }
+
+        private void SearchWorkerThread_DoWork(object sender, DoWorkEventArgs e)
+        {
+
+        }
+
+        private void SearchWorkerThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
+        {
+
+        }
+
+        private void SearchWorkerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
+        {
+
+        }
+
+        private void search_progress_updater_Tick(object sender, EventArgs e)
+        {
+            if ((this.AcceptedProcess ==null) || Process.GetProcessById(this.AcceptedProcess.Id) == null)
+            {
+                SearchWorkerThread.CancelAsync();
+                //JokerSearchWorker.CancelAsync();
+                ResultsUpdateWorkerThread.CancelAsync();
+            }
+        }
+
+        private void btnSearch_Click(object sender, EventArgs e)
+        {
+            this.FreezeResultsUpdate();
+        }
     }
 }

 

  ViewVC Help
Powered by ViewVC 1.1.22