|
the code sample i gave you puts the class in charge of refreshing the data in total control, the one call made in the UI is just letting the GrowingTable class know how to perform tasks in sync with the UI thread. after that stage has been performed the UI has no more involvement.
I'm glad you have found a solutino but the assumptin that the form is callint InvokeOnUI is not quite right.
|
|
|
|
|
Well, it works. Not sure about design quality, but it was better than the hacks I was using before. Thanks for all the help! Let me know if it sucks. Here's a sample which demonstrates the pattern; first the caller/form:
using System;
using System.Windows.Forms;
using GrowingDataTable;
namespace dgv
{
public partial class Form1 : Form
{
public DataGridView dgvMain;
public delegate void delEventHandler(object sender,
GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs e);
public GrowingDataTable gt;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dgvMain = new DataGridView();
Controls.Add(dgvMain);
dgvMain.Dock = System.Windows.Forms.DockStyle.Fill;
gt = new GrowingDataTable();
gt.RaiseUpdateTableAgainstYourThreadContextEvent += new
EventHandler<GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs>
(gt_RaiseUpdateTableAgainstYourThreadContextEvent);
gt.UpdateDataTableOnCallerThreadContext = true;
dgvMain.DataSource = gt.itemTable;
gt.Start(3000, 1000);
}
void gt_RaiseUpdateTableAgainstYourThreadContextEvent(object sender,
GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs e)
{
if (InvokeRequired) {
Invoke(new
delEventHandler(gt_RaiseUpdateTableAgainstYourThreadContextEvent),
new object[] { sender, e}); }
else
{
if ((e.Updates != null) || (e.Updates.Count > 0))
{
gt.UpdateTableOnMyThreadContext(e.Updates);
}
}
}
}
}
Then the library class GrowingDataTable:
using System;
using System.Collections.Concurrent;
namespace GrowingDataTable
{
public class GrowingDataTable
{
public System.Data.DataTable itemTable;
public System.Threading.Timer myTimer = null;
private ConcurrentQueue<System.Data.DataRow> qUpdates = new
ConcurrentQueue<System.Data.DataRow>();
public GrowingDataTable()
{
itemTable = new System.Data.DataTable();
myTimer = new System.Threading.Timer(this.AddRows, null,
System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
for (int i = 0; i < 10; i++) {
itemTable.Columns.Add(new System.Data.DataColumn
(i.ToString(), typeof(System.DateTime))); }
}
public bool UpdateDataTableOnCallerThreadContext { get; set; }
public class UpdateDataTableOnYourThreadContextEventArgs : EventArgs
{
private ConcurrentQueue<System.Data.DataRow> qu;
public UpdateDataTableOnYourThreadContextEventArgs
(ConcurrentQueue<System.Data.DataRow> Qu)
{
qu = Qu;
}
public ConcurrentQueue<System.Data.DataRow> Updates
{
get { return qu; }
}
}
public event EventHandler<UpdateDataTableOnYourThreadContextEventArgs>
RaiseUpdateTableAgainstYourThreadContextEvent;
public void UpdateTableOnMyThreadContext(
ConcurrentQueue<System.Data.DataRow> Q)
{
System.Data.DataRow dr = null;
while (Q.TryDequeue(out dr))
{
if (dr != null)
{
itemTable.Rows.Add(dr);
}
}
}
public void Start(int delay, int interval)
{
myTimer.Change(delay, interval);
}
private void AddRows(object state)
{
if (itemTable.Rows.Count < 10)
{
System.Data.DataRow dr = this.itemTable.NewRow();
for (int i = 0; i < 11; i++) { dr[i.ToString()] = DateTime.Now; }
if (UpdateDataTableOnCallerThreadContext)
{
qUpdates.Enqueue(dr);
OnRaiseUpdateDataTableAgainstYourThreadContextEvent(new
UpdateDataTableOnYourThreadContextEventArgs(qUpdates));
}
else
{
this.itemTable.Rows.Add(dr);
}
}
else
{
myTimer.Dispose();
myTimer = null;
}
}
protected virtual void OnRaiseUpdateDataTableAgainstYourThreadContextEvent(
UpdateDataTableOnYourThreadContextEventArgs q)
{
EventHandler<UpdateDataTableOnYourThreadContextEventArgs> handler =
RaiseUpdateTableAgainstYourThreadContextEvent;
if (handler != null)
{
handler(this, q);
}
}
}
}
|
|
|
|
|
Hello Friends,,
well this is the situation im trying to simulate Keys but only when a proccess is actually running
this is what i have
Private Sub letter_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles letter.Tick
Dim rprocess() As System.Diagnostics.Process = Process.GetProcessesByName("Test.exe")
If System.IO.File.Exists("C:\test\Listener.txt") Then
Else
System.IO.File.Create("C:\Test\Listener.txt")
End If
If rprocess.Length = 1 Then
ElseIf (GetAsyncKeyState(Keys.A)) Then
Dim ReadIt As String = System.IO.File.ReadAllText("C:\Test\Listener.txt")
System.IO.File.WriteAllText("C:\Test\Listener.txt", ReadIt & "A")
End If
End Sub/pre>
but is stil reading the "A" even if the proccess is off or not present .. HELP !!
|
|
|
|
|
SORRY WORLD .. found the problem =)
if anyone tries then is
if rprocess.length = 1 then
getasynckeystate(keys.a)
remove elseif and the "()"
|
|
|
|
|
Hi Everyone,
I did a search on capturing screen shots in vb.net and I was wondering if there is a straight forward way to capture the active window? Or do I need to first get the handle of the active window, get the position and size and then capture it? I do not want to use any type of sendkeys method or use the clipboard. I want to save it to jpg format.
Thanks!
Done so far but its capturing the entire window is
Module patternAload
Private Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As String) As Integer
Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer
Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer
Private Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" (ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer
Private Declare Function BitBlt Lib "GDI32" (ByVal srchDC As Integer, ByVal srcX As Integer, ByVal srcY As Integer, ByVal srcW As Integer, ByVal srcH As Integer, ByVal desthDC As Integer, ByVal destX As Integer, ByVal destY As Integer, ByVal op As Integer) As Integer
Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer
Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer
Declare Function GetForegroundWindow Lib "user32" Alias "GetForegroundWindow" () As Integer
Const SRCCOPY As Integer = &HCC0020
Private oBackground As Bitmap
Private FW, FH As Integer
Public Sub CaptureScreen()
Dim hSDC, hMDC As Integer
Dim hBMP, hBMPOld As Integer
Dim r As Integer
Dim fgw As Long = GetForegroundWindow()
hSDC = CreateDC("DISPLAY", "", "", "")
hMDC = CreateCompatibleDC(hSDC)
FW = GetDeviceCaps(hSDC, 8)
FH = GetDeviceCaps(hSDC, 10)
hBMP = CreateCompatibleBitmap(hSDC, FW, FH)
hBMPOld = SelectObject(hMDC, hBMP)
r = BitBlt(hMDC, 40, 40, FW, FH, hSDC, 0, 0, SRCCOPY)
hBMP = SelectObject(hMDC, hBMPOld)
r = DeleteDC(hSDC)
r = DeleteDC(hMDC)
oBackground = Image.FromHbitmap(New IntPtr(hBMP))
DeleteObject(hBMP)
End Sub
|
|
|
|
|
I suspect that the following code should help:
<DllImport("user32.dll")> _
Public Shared Function GetForegroundWindow() As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As RECT) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", ExactSpelling := True, CharSet := CharSet.Auto)> _
Private Shared Function SetForegroundWindow(hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
Public Shared Sub CaptureWindow(fileName As String, format As ImageFormat)
Dim hWnd As IntPtr = GetForegroundWindow()
If hWnd = IntPtr.Zero Then
Return
End If
Dim srcRect As RECT
If Not GetWindowRect(hWnd, srcRect) Then
Return
End If
Dim width As Integer = srcRect.Right - srcRect.Left
Dim height As Integer = srcRect.Bottom - srcRect.Top
Using bmp As New Bitmap(width, height)
Using g As Graphics = Graphics.FromImage(bmp)
g.CopyFromScreen(srcRect.Left, srcRect.Top, 0, 0, New Size(width, height), CopyPixelOperation.SourceCopy)
bmp.Save(fileName, format)
End Using
End Using
End Sub If you want to do it in C#, the same code would look like this:
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public static void CaptureWindow(string fileName, ImageFormat format)
{
IntPtr hWnd = GetForegroundWindow();
if (hWnd == IntPtr.Zero) return;
RECT srcRect;
if (!GetWindowRect(hWnd, out srcRect)) return;
int width = srcRect.Right - srcRect.Left;
int height = srcRect.Bottom - srcRect.Top;
using (Bitmap bmp = new Bitmap(width, height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(srcRect.Left, srcRect.Top, 0, 0,
new Size(width, height), CopyPixelOperation.SourceCopy);
bmp.Save(fileName, format);
}
}
}
|
|
|
|
|
OK i will retry with this code lets see what happens ..
Thanks
|
|
|
|
|
|
i got confused sorry ... so the public sub to save the file will be ???
i try Private Sub Form1_load()
CaptureWindow(fileName:="C:\test.jpg", format:="")
bmp.Save("C:\test.jpg")
End Sub
and its not working
|
|
|
|
|
hey my bad im sorry =)
i got it
bmp.Save("test.bmp", jpeg)
i did change it and it wasnt working i had to put
bmp.save("c:\test.bmp", system.drawing.imaging.ImageFormat.Jpeg)
and on the click
CaptureWindow("C:\test.bmp", Jpeg)
that was it
Thanks
|
|
|
|
|
Sweet. Not too bad when you consider I just knocked that up in Notepad. I'm glad it's working for you.
|
|
|
|
|
hehe Thanks a lot man
i have another question its killing me lol ima post the new topic =) is different lol .. thanks a gain man
|
|
|
|
|
I have an application that uses Comparer class to compare the objects. In 4.0 framework, the function public int Compare(object a, object b) took much time than 2.0. Please help me to resolve this issue!!!
modified 8-Aug-12 8:32am.
|
|
|
|
|
Could you show us the code you were using here? That might help to narrow things down.
|
|
|
|
|
Thanks for your reply. When i change the Target FrameWork from 4 to 2 in Project Properties in VS 10, it took less time.
Please find the below code snippet:
public static int CompareKeyColumn(DataRow drSource, DataRow drTarget, ArrayList arrForeignKey)
{
int iComareVal = 0;
string strColumnName = "";
Comparer cRow = new Comparer(new CultureInfo("es-ES", false));
for (int j = 0; j < arrForeignKey.Count; j++)
{
strColumnName = arrForeignKey[j].ToString();
if (drSource[strColumnName] != DBNull.Value && drTarget[strColumnName] != DBNull.Value)
{
iComareVal = cRow.Compare(drSource[strColumnName], drTarget[strColumnName]);
}
else if (drSource[strColumnName] == DBNull.Value)
iComareVal = -1;
else if (drTarget[strColumnName] == DBNull.Value)
iComareVal = 1;
if (iComareVal > 0)
return 1;
else if (iComareVal < 0)
return -1;
}
return 0;
}
|
|
|
|
|
My suspicion is that the problem actually lies with the culture. This is what happens inside Compare:
public int Compare(object a, object b)
{
if (a == b)
{
return 0;
}
if (a == null)
{
return -1;
}
if (b == null)
{
return 1;
}
if (this.m_compareInfo != null)
{
string str = a as string;
string str2 = b as string;
if ((str != null) && (str2 != null))
{
return this.m_compareInfo.Compare(str, str2);
}
}
IComparable comparable = a as IComparable;
if (comparable == null)
{
throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
}
return comparable.CompareTo(b);
} To test this hypothesis out, try dropping the CultureInfo out and see what happens. (The m_compareInfo.Compare part is the test that occurs when you set the CultureInfo ).
|
|
|
|
|
Sorry! I didnt get your answer. How to drop the CultureInfo? May i use Comparer.Default.Compare(object a, object b) function?
|
|
|
|
|
To test it, change
Comparer cRow = new Comparer(new CultureInfo("es-ES", false)); to
Comparer cRow = new Comparer();
|
|
|
|
|
I couldnt do it. The Comparer Constructor must take CultureInfo as Parameter. Default constructor is not available!!!
|
|
|
|
|
Doh. Of course it isn't. Sorry about that. OK, use the Comparer.Default.Compare(object, object) method to test the timings.
|
|
|
|
|
Ok. I will try and let you know
|
|
|
|
|
ruby_e_s wrote: I will try and let you know
Looking forward to seeing it.
|
|
|
|
|
Yeah! Now Framework 4 also took less time!!! Thanks for your help...
|
|
|
|
|
Not a problem. I'm glad I could help.
|
|
|
|
|
how to draw ecg waveform in wpf please anyone give tips...advance in thanks whomever helping me...thanks friends...
|
|
|
|
|