|
Hi.
Can you make the orientation of a Windows Forms ProgressBar to be vertically?
Thanks.
|
|
|
|
|
|
hi big guns. i got a problem how to compare the contents of two are more files. plz plz help me
tahir shah
|
|
|
|
|
please explain what you want. What kind of files, big/small, what kind of result.
is it bool AreIdentical(), or string[] GetDifferences(), or ... ?
Luc Pattyn
|
|
|
|
|
how do i override the behaviour performed when the column header of a datagrid is clicked to sort the rows according to that column? thanks!
I am a SysAdmin, I battle my own daemons.
|
|
|
|
|
I have tried to make a multi-tab browser using some of the information from this[^] post. I have a button that opens up a new tab with a browser in it. But when i go back to the other tab, the browser is gone from that tab! The code i used is...
tabControlBrowser.TabPages.Add("http://www.google.com");
int tabCount = tabControlBrowser.TabCount;
tabControlBrowser.TabPages[tabCount - 1].Controls.Add(webBrowser);
tabControlBrowser.SelectTab(tabCount - 1);
Your help is appreciated!!!
|
|
|
|
|
dsl/fahk wrote: tabControlBrowser.TabPages[tabCount - 1].Controls.Add(webBrowser);
You're moving your webbrowser control between pages, instead of creating a new one
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Hi,
I have to paste a string value to a remote application powered by Citrix. I tried using SendKeys with "(^V)". Then I used the following,
PostMessage(handle,WM_KEYDOWN,Controlkey,IntPtr.Zero);
PostMessage(handle,WM_KEYDOWN,V,IntPtr.Zero);
PostMessage(handle,WM_KEYUP,V,new IntPtr(1));
PostMessage(handle,WM_KEYUP,Controlkey,new IntPtr(1));
This doesn't work either.
Then I tried Sending keys relavent to the pasting value usaing above PostMessage(). i.e. if I have to paste "123" I send three PostMessage calls with 1,2,3 key values respectively. It didn't work too.
Anyway I have pass the value to clipboard. I have the process ID of the remote application too. with these information is there a way to transfer data from clipboard to remote application?
Any help would be great.
Thank you.
Regards,
Sampathg
|
|
|
|
|
Some suggestions:
1.
I dont like "new IntPtr(1)"; you do not intend to send a pointer, so use another function prototype that accepts an int or uint instead of an IntPtr.
(FYI, if you really needed to send a buffer pointer to another process, it should be
meaningful to that process, see e.g. VirtualAllocEx)
2.
WM_KEYUP lParam=repeat count, so it should really be zero, not one.
3.
how did you get the handle ? are you sure it is correct ? did you try some other operation
with it, e.g. a hide/show by sending (showCommand=0/1):
[DllImport("user32", SetLastError=true)]
public static extern uint ShowWindow (IntPtr hWnd, int showCommand);
Cheers
Luc Pattyn
|
|
|
|
|
Hi Luc,
First of all thanks a lot on commenting.
Let me explain you this bit..
I have to paste the value to a window which is a remote application. And the bad thing is this application opens in a remote desktop. I'm not allowed to install or do any change on that desktop. So I only can get the windows handle or the Process Id of the remote desktop window. Then I was able to simulate a mouse click on the relavent textbox. At this point if I use the keyboard "Ctrl+V" for pasting it works. But when I use the code, it doesn't work. With Microsoft.VisualBasic.Keyboard.SenKeys it worked once. But now I get an error saying "you have to enable windows Messaging".
I hope you get a better idea.
Please comment on the isuues.
Thanks a lot.
Sampathg
|
|
|
|
|
Hi Sampathg,
If I understand you correctly, you have a window belonging to some fixed program (the remote desktop app), and when you click a textbox in there, then type ^V, the paste works (and
the pasted stuff probably shows up on the local and the remote PC). Thats what we all expect.
So now you want to programmatically do the same. I guess you need the handle of the textbox
and do the SendMessage stuff. Getting the handle is somewhat tricky; you first need the
handle of the form, then find the textbox in the form's hierarchy of controls.
The only way I know consists of:
- the Win32 method EnumWindows()
remember every control that is or can be visible in the end is a window
remark: it can be nested, just like you can put a button in a panel in a panel in a form.
- a lot of trial and error to identify the right window from the many available
(at first type a known text in the textbox, and try to copy it sending ^C,
you should get label texts and other things you may be able to recognize
I tend to be careful with the code inside the callback method, and do as much as possible
outside it (hence the ArrayList in the example below).
FYI I once wrote:
public delegate bool LP_EnumWindowsProc(IntPtr hWnd, int lParam);
public static ArrayList GetVisibleWindowHandles() {
lock(env) {
list=new ArrayList();
EnumWindows(new LP_EnumWindowsProc(CollectVisibleWindows), 0);
env.log(env.DETAIL1, "There are "+list.Count+" visible windows");
return list;
}
}
private static void CollectVisibleWindows(IntPtr hWnd, int lParam) {
IntPtr ptr=(IntPtr)hWnd;
if (IsWindowVisible(ptr)) {
list.Add(ptr);
}
}
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int EnumWindows(LP_EnumWindowsProc ewp, object lParam);
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern bool IsWindowVisible(IntPtr hWnd);
Final remark:
you might want to experiment first with a very simple target program that you develop
yourself. But dont expect the handle values to match, I'm pretty sure handle values
are local to the process (but SendMessage will convert them without you worrying about it).
Hope this helps.
Luc Pattyn
|
|
|
|
|
Hi Sampathg,
same message with "ignore HTML tags" !
If I understand you correctly, you have a window belonging to some fixed program (the remote desktop app), and when you click a textbox in there, then type ^V, the paste works (and
the pasted stuff probably shows up on the local and the remote PC). Thats what we all expect.
So now you want to programmatically do the same. I guess you need the handle of the textbox
and do the SendMessage stuff. Getting the handle is somewhat tricky; you first need the
handle of the form, then find the textbox in the form's hierarchy of controls.
The only way I know consists of:
- the Win32 methods EnumWindows() and EnumChildWindows()
remember every control that is or can be visible in the end is a window
remark: it can be nested, just like you can put a button in a panel in a panel in a form.
- a lot of trial and error to identify the right window from the many available
(at first type a known text in the textbox, and try to copy it sending ^C,
you should get label texts and other things you may be able to recognize
I tend to be careful with the code inside the callback method, and do as much as possible
outside it (hence the ArrayList in the example below).
FYI I once wrote:
<pre>
/// <summary>
/// delegate used for EnumWindows() callback function
/// </summary>
public delegate bool LP_EnumWindowsProc(IntPtr hWnd, int lParam);
/// <summary>
/// Gets a collection of all visible windows on the desktop.
/// </summary>
/// <returns></returns>
/// <remarks>The result may include some minimized windows too !</remarks>
public static ArrayList GetVisibleWindowHandles() {
lock(env) {
list=new ArrayList();
EnumWindows(new LP_EnumWindowsProc(CollectVisibleWindows), 0);
env.log(env.DETAIL1, "There are "+list.Count+" visible windows");
return list;
}
}
private static bool CollectVisibleWindows(IntPtr hWnd, int lParam) {
IntPtr ptr=(IntPtr)hWnd;
if (IsWindowVisible(ptr)) {
list.Add(ptr);
}
return true; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< correction !
}
/// <summary>
/// Enumerate all windows, calling a delegate for each of them.
/// </summary>
/// <param name="ewp"></param>
/// <param name="lParam"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int EnumWindows(LP_EnumWindowsProc ewp, object lParam);
/// <summary>
/// Determines whether a window is visible.
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
public static extern bool IsWindowVisible(IntPtr hWnd);
</pre>
Final remark:
you might want to experiment first with a very simple target program that you develop
yourself. Window handle values are system wide so your test target program could obtain
and display the handle you are interested in, just so you can check it.
Hope this helps.
Luc Pattyn
-- modified at 22:43 Sunday 14th January, 2007
|
|
|
|
|
On the SendKeys topic:
1.
What is the exact error message you get with Microsoft.VisualBasic.Keyboard.SendKeys ?
who is reporting this: the remote app, or your app, and how and when ?
did you Google the exact message ?
2.
there is System.Windows.Forms.SendKeys, which maybe similar/identical to the VB one.
3.
but as far as I can tell this expects the textbox to be focused, which may or may not be the case.
Cheers,
Luc Pattyn
|
|
|
|
|
Hi Luc,
Answers:
1) Full error message as follows,
"An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method."
Error reported by the following line of my code
board.SendKeys("1234");
Yes, I searched it...but not much use.
I used the SendKeys.SendWait and it didn't work too.
2). I first used System.Windows.Forms.SendKeys. It doesn't paste the value. No errors. But nothing happens.
3).
Textbox is focused before use the Automatic keystroke simulation. I commented the SendKeys function and at that point I manually pressed Ctrl+V. It worked.
Hope I explianed it clearly.
Thanks a lot.
Sampathg
|
|
|
|
|
Hello again,
I Googled your error message and found an MSDN article[^] that suggests using SendInput rather than SendKeys (although it is a
bit more difficult to use).
Regards,
Luc Pattyn
|
|
|
|
|
Hi Luc,
I tried SendInput. Still it doesn't work. Seams some thing wrong with the remote application. So waiting for customers response.
Thanks a lot for the help.
Rgds,
Sampathg
|
|
|
|
|
Hi,
I have an autocomplete textbox populated with a list by [LastName, FirstName] of all my members obtained from a datatable at runtime - works well
What I want to do is to have the details of that member displayed on the form without any other user interaction other than typing in the members name in the textbox.
I have enabled a "textchanged" event which will then change the bindingsource.position but here is where I have a problem.
How do I get the position number of the current member in the textbox so that I can change the bindingsouce position?
I don't want to include the postion number of the member in the textbox field and then parse it out - would look most unprofessional.
I also don't want to do another search on the datatable just to get the position number - lots of duplicated processing.
I thought about changing the textbox tag as you move thru the member list and passing that to the event but I can't work that out either.
Any suggestions will be welcomed.
Glen Harvy
|
|
|
|
|
I have a datagridview and would like one of it's txtBox columns to contain the Current date by default. Which of the datagridview's events should I use to be able to assign to it's EdittedFormatedValue or something?
Live in fragments no longer. Only connect.
|
|
|
|
|
There's more than one way to approach this.
One way is to set the DataGridViewTextBoxColumn's DefaultValue property to the current date. This means that all rows with an unspecified value in that column will get the current date. One problem is that the date will remain the same even if the date changes while the application is still running (i.e. new rows will still get the no-longer-current date).
Another approach is to use the DataGridView's DefaultValuesNeeded event to set the current date, e.g. (if the target DataGridViewTextBoxColumn is named "DateColumn"):
private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
{
e.Row.Cells["DateColumn"].Value = DateTime.Now.ToShortDateString();
}
This affects only new rows; existing rows will not be updated.
If you do both, then existing rows with an unspecified value will get the date on which the application began running and new rows will get the current date.
|
|
|
|
|
Thanks Lisa
Live in fragments no longer. Only connect.
|
|
|
|
|
i am creating an application that sends something on the parallel port(d0-d7) and then reads 3 status registers...i was able to send the data using inpout32.dll but i do not know how to read the status registers...my app has to listen for any changes of these status registers and act acording to the changes...if anyone could help i would appreciate it
|
|
|
|
|
|
Hello all.
I've got a common multithreading predicament that might look easy to solve, but I'm looking for best practice. I got some sloppy ideas myself, but I'd like to hear what should be best used in this situation.
1- I'm fetching data from the network server -No problem. Takes about 3-7 secs-.
2- Then I'm populating/refreshing a TreeView from that DataTable which could contain up to 30,000+ records. This is the problem as this takes about 2-3 mins.
I can't allow step two to hold off the user for 2-3 mins until the list is filled. I decided to make another thread to fill up the TreeView while the user still can interact with the rest of the UI. Two questions:
1- Is it normal that a TreeView takes 2-3 mins on a modern Centrino 1.83 laptop with 1.5 GB RAM to add 30,00 nodes? How to speed it up?
2- I got a refresh button that should cancel that active thread, clear the TreeView, then refresh it with node. If I press it twice quickly with my current code, the UI freezes. Any ideas?
If you need to take a look at my sloppy code -Here! Have a nice laugh at it!-, here it is:
private bool StopPopulating;
private delegate void ClearDel();
private delegate TreeNode AddDel(string text);
internal void PopulateList()
{
if (!IsPopulating && StopPopulating)
return;
IsPopulating = false;
StopPopulating = true;
while (Populator != null && Populator.IsAlive)
Thread.Sleep(1);
Populator = new Thread(new ThreadStart(PopulateMethod));
Populator.IsBackground = true;
Populator.Priority = ThreadPriority.Lowest;
IsPopulating = true;
StopPopulating = false;
Populator.Start();
}
private void PopulateMethod()
{
lock ("Populating")
{
try
{
ClearDel clearing = new ClearDel(Patients.Nodes.Clear);
AddDel adding = new AddDel(Patients.Nodes.Add);
Patients.BeginInvoke(clearing);
CathProxy PatientsProxy = (CathProxy)Activator.GetObject(typeof(CathProxy), CathLab.Url);
DataTable mvps = new DataTable();
DataTable Pts = PatientsProxy.GetList(out mvps);
TreeNode CurrentNode;
foreach (DataRow r in Pts.Rows)
{
if (StopPopulating)
return;
CurrentNode = (TreeNode)Patients.EndInvoke(Patients.BeginInvoke(adding, new object[] { '(' + r["Hospital_Number"].ToString() + ") " + r["Patient_Name"].ToString() }));
foreach (DataRow ro in mvps.Rows)
{
if (r["Hospital_Number"].ToString() == ro["Hospital_Number"].ToString())
{
AddDel curadd = new AddDel(CurrentNode.Nodes.Add);
Patients.BeginInvoke(curadd, new object[] { "MVP at " + DateTime.Parse(ro["Procedure_Date"].ToString()).ToShortDateString() });
}
}
}
}
catch (SystemException ex)
{
MessageBox.Show(ex.Message, "Error populating patients list");
}
finally
{
IsPopulating = false;
}
}
}
waiting for bright ideas as I'm out of caffeine!
Regards
|
|
|
|
|
1. I don't have a direct comparison, but 2-3 minutes to create a 30,000 node TreeView seems slow. I think your performance problem is due to two things: making individual TreeView updates and making those updates via individual BeginInvoke() calls. On my 1.63GHz Core2 Duo, it takes about 45 seconds when updates are performed individually from within a loop on the UI thread. When batching the updates, that time was cut down to 20 seconds.
Using Control.Invoke() or Control.BeginInvoke() is a relatively expensive operation due to all of the coordination necessary to shift to and execute the delegate on the UI thread. While it's necessary in order to update the UI from a worker thread, it should not be used in "tight loop" situations. Instead, one should make a single Invoke()/BeginInvoke() call and make *all* the updates from within that single delegate.
This model also allows one to make use of the Control.BeginUpdate() and Control.EndUpdate() methods. These disable and reenable drawing of the control. By adding your new nodes in between those method calls, the system will add them without repeatedly refreshing the control display, and therefore, will add them more quickly.
2. You're likely seeing the UI freeze due to your Thread.Sleep(1) in your PopulateList() method. If this is being called on the UI thread, it effectivly stops the Windows message pump until the thread exits. Blocking on the UI thread is strongly discouraged. If your thread is also interacting with the message pump (e.g. by making Control.Invoke() calls), you could also be setting up a deadlock situation.
One trick to prevent the "impatient user multiple-click" is to disable the button on the first click and only reenable it once the resulting action is complete.
-Phil
|
|
|
|
|
Thanks for your very valuable help. I really appreciate it.
Actually about the "impatient user multiple-click" issue. The list is updated by several events, so I can't really have control on the refreshing. I need that when the user triggers an event that requires refreshment that the current thread is gracefully terminated, and a new thread started again.
I've made a few adjustment to the code. Now My main thread freezes even though I use BeginInvoke(). Any idea way.
internal void PopulateList()
{
Populator = new Thread(new ThreadStart(PopulateMethod));
Populator.IsBackground = true;
Populator.Priority = ThreadPriority.BelowNormal;
IsPopulating = true;
StopPopulating = false;
Populator.Start();
}
private void PopulateMethod()
{
lock ("Populating")
{
try
{
CathProxy PatientsProxy = (CathProxy)Activator.GetObject(typeof(CathProxy), CathLab.Url);
DataTable mvps = new DataTable();
DataTable Pts = PatientsProxy.GetList(out mvps);
updateDel update = new updateDel(UpdateList);
this.BeginInvoke(update, new object[] { Pts, mvps });
}
catch (SystemException ex)
{
MessageBox.Show(ex.Message, "Error populating patients list");
}
}
}
private void UpdateList(DataTable Pts, DataTable mvps)
{
Patients.Nodes.Clear();
TreeNode PleaseWait = Patients.Nodes.Add("Refreshing list. Please Wait");
Patients.BeginUpdate();
foreach (DataRow r in Pts.Rows)
{
if (StopPopulating)
return;
TreeNode CurrentNode = Patients.Nodes.Add('(' + r["Hospital_Number"].ToString() + ") " + r["Patient_Name"].ToString());
foreach (DataRow ro in mvps.Rows)
{
if (r["Hospital_Number"].ToString() == ro["Hospital_Number"].ToString())
CurrentNode.Nodes.Add("MVP at " + DateTime.Parse(ro["Procedure_Date"].ToString()).ToShortDateString());
}
}
PleaseWait.Remove();
Patients.EndUpdate();
IsPopulating = false;
StopPopulating = false;
}
Thanks again for your time.
Regards
|
|
|
|
|