|
|
I've been trying to figure out how to extract information from all the windows presently on the desktop for about a week now. I've made it a ways, but now I am most thoroughly stuck. The following code I've gathered from various places. It compiles fine in VS 2005 RC1 against the .NET 2.0 framework.
However, at runtime it gets hung up when trying to return the windowlist. It gives a generic error and stops execution when it attemps to run the following line:
foreach (Window x in Windows)<br />
{<br />
Windows.Add(x.Title + ": " + x.hWnd.ToString());<br />
}
Here is the entire rest of the code. It should compile for you fine, with a simple cut and paste job.
I really need to get this code working. If you have the time, and want to chat: my AIM is navinineteen.
The following is two separate files:
<br />
using System;<br />
using System.Drawing;<br />
using System.Collections;<br />
using System.ComponentModel;<br />
using System.Windows.Forms;<br />
using System.Data;<br />
<br />
namespace WindowScraper<br />
{<br />
public class FormWindowList : System.Windows.Forms.Form<br />
{<br />
<br />
private System.Windows.Forms.ListBox listBoxWindowList;<br />
private System.Windows.Forms.Button buttonUpdateWindowsList;<br />
private System.Windows.Forms.Button buttonSaveImage;<br />
private System.ComponentModel.Container components = null;<br />
<br />
public FormWindowList()<br />
{<br />
InitializeComponent();<br />
<br />
}<br />
<br />
protected override void Dispose( bool disposing )<br />
{<br />
if( disposing )<br />
{<br />
if (components != null) <br />
{<br />
components.Dispose();<br />
}<br />
}<br />
base.Dispose( disposing );<br />
}<br />
<br />
#region Windows Form Designer generated code<br />
private void InitializeComponent()<br />
{<br />
this.listBoxWindowList = new System.Windows.Forms.ListBox();<br />
this.buttonUpdateWindowsList = new System.Windows.Forms.Button();<br />
this.buttonSaveImage = new System.Windows.Forms.Button();<br />
this.SuspendLayout();<br />
this.listBoxWindowList.Location = new System.Drawing.Point(16, 16);<br />
this.listBoxWindowList.Name = "listBoxWindowList";<br />
this.listBoxWindowList.Size = new System.Drawing.Size(256, 173);<br />
this.listBoxWindowList.TabIndex = 0;<br />
this.buttonUpdateWindowsList.Location = new System.Drawing.Point(64, 200);<br />
this.buttonUpdateWindowsList.Name = "buttonUpdateWindowsList";<br />
this.buttonUpdateWindowsList.Size = new System.Drawing.Size(160, 23);<br />
this.buttonUpdateWindowsList.TabIndex = 1;<br />
this.buttonUpdateWindowsList.Text = "Update Windows List";<br />
this.buttonUpdateWindowsList.Click += new System.EventHandler(this.UpdateWindowList);<br />
this.buttonSaveImage.Location = new System.Drawing.Point(64, 232);<br />
this.buttonSaveImage.Name = "buttonSaveImage";<br />
this.buttonSaveImage.Size = new System.Drawing.Size(160, 23);<br />
this.buttonSaveImage.TabIndex = 2;<br />
this.buttonSaveImage.Text = "Save Image";<br />
this.buttonSaveImage.Click += new System.EventHandler(this.SaveImage);<br />
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);<br />
this.ClientSize = new System.Drawing.Size(292, 273);<br />
this.Controls.Add(this.buttonSaveImage);<br />
this.Controls.Add(this.buttonUpdateWindowsList);<br />
this.Controls.Add(this.listBoxWindowList);<br />
this.Name = "FormWindowList";<br />
this.Text = "Window List";<br />
this.ResumeLayout(false);<br />
<br />
}<br />
#endregion<br />
<br />
[STAThread]<br />
static void Main() <br />
{<br />
Application.Run(new FormWindowList());<br />
}<br />
<br />
private void UpdateWindowList(object sender, System.EventArgs e)<br />
{<br />
listBoxWindowList.Controls.Clear();<br />
<br />
ArrayList windows = WindowScraper.GetWindowList();<br />
foreach (string window in windows)<br />
listBoxWindowList.Items.Add(window);<br />
}<br />
<br />
private void SaveImage(object sender, System.EventArgs e)<br />
{<br />
<br />
}<br />
<br />
}<br />
}<br />
... and the second file.
<br />
<br />
using System;<br />
using System.Collections;<br />
using System.Text;<br />
using System.Runtime.InteropServices;<br />
<br />
namespace WindowScraper<br />
{<br />
public class WindowScraper<br />
{<br />
public static ArrayList Windows;<br />
<br />
public struct Window<br />
{<br />
public string Title;<br />
public int hWnd;<br />
public Window(string Title, int hWnd)<br />
{<br />
this.Title = Title;<br />
this.hWnd = hWnd;<br />
}<br />
}<br />
<br />
<br />
<br />
private const int GWL_EXSTYLE = (-20);<br />
private const int WS_EX_TOOLWINDOW = 0x80;<br />
private const int WS_EX_APPWINDOW = 0x40000;<br />
private const int GW_OWNER = 4;<br />
<br />
public delegate int EnumWindowsProcDelegate(int hWnd, int lParam);<br />
<br />
[DllImport("user32")]<br />
private static extern int EnumWindows(EnumWindowsProcDelegate lpEnumFunc, int lParam);<br />
<br />
[DllImport("User32.Dll")]<br />
public static extern void GetWindowText(int h, StringBuilder s, int nMaxCount);<br />
<br />
[DllImport("user32", EntryPoint = "GetWindowLongA")]<br />
private static extern int GetWindowLongPtr(int hwnd, int nIndex);<br />
<br />
[DllImport("user32")]<br />
private static extern int GetParent(int hwnd);<br />
<br />
[DllImport("user32")]<br />
private static extern int GetWindow(int hwnd, int wCmd);<br />
<br />
[DllImport("user32")]<br />
private static extern int IsWindowVisible(int hwnd);<br />
<br />
[DllImport("user32")]<br />
private static extern int GetDesktopWindow();<br />
<br />
<br />
private static bool IsTaskbarWindow(int hWnd)<br />
{<br />
int lExStyle;<br />
int hParent;<br />
lExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);<br />
hParent = GetParent(hWnd);<br />
bool fTaskbarWindow = ((IsWindowVisible(hWnd) != 0) & (GetWindow(hWnd, GW_OWNER) == 0) & (hParent == 0 | hParent == GetDesktopWindow()));<br />
if ((lExStyle & WS_EX_TOOLWINDOW) == WS_EX_TOOLWINDOW)<br />
{<br />
fTaskbarWindow = false;<br />
}<br />
if ((lExStyle & WS_EX_APPWINDOW) == WS_EX_APPWINDOW)<br />
{<br />
fTaskbarWindow = true;<br />
}<br />
return fTaskbarWindow;<br />
}<br />
<br />
<br />
public static int EnumWindowsProc(int hWnd, int lParam)<br />
{<br />
if (IsTaskbarWindow(hWnd))<br />
{<br />
StringBuilder sb = new StringBuilder(1024);<br />
GetWindowText(hWnd, sb, sb.Capacity);<br />
String xMsg = sb.ToString();<br />
{<br />
if (xMsg.Length > 0)<br />
{<br />
Windows.Add(new Window(xMsg, hWnd));<br />
}<br />
}<br />
}<br />
return 1;<br />
}<br />
<br />
public static ArrayList GetWindowList()<br />
{<br />
Windows = new ArrayList();<br />
EnumWindows(EnumWindowsProc, 0);<br />
foreach (Window x in Windows)<br />
{<br />
Windows.Add(x.Title + ": " + x.hWnd.ToString());<br />
}<br />
return Windows;<br />
}<br />
<br />
}<br />
}<br />
<br />
|
|
|
|
|
I didn't look at the whole code block you posted, but only the first part. I noticed there is a big problem that will cause it to crash:
<br />
foreach (Window x in Windows)<br />
{<br />
Windows.Add(x.Title + ": " + x.hWnd.ToString());<br />
}<br />
You'll notice that you're saying for every Window object in the Windows IList you are adding a new windows object to the IList.
Windows.Add is adding a new Window to the list you are enumerating!! This will cause it to never end and eventually run out of memory. Now the compiler is supposed to tell you that you can't change the value of a list while it's in use in a loop, but who knows why it didn't.
|
|
|
|
|
Can anybody give me any information on creating a taskbar application (ie when you minimize windows media player, or TrueLaunchBar). Any information or links would be great.
Thanks
JGA
|
|
|
|
|
How can I determine the col number and row number of the current cursor position in a richTextBox control?? I really need that very fast.
Regards
|
|
|
|
|
Use GetLineFromCharIndex(theRichTextBox.SelectionStart) to retrieve the line/row number.
To get the column number you'll have to count the characters from SelectionStart backwards until you reach '\n'.
Regards,
mav
|
|
|
|
|
Im now starting to think of developing a big chat system
which will need to handle up to 1000 clients connected at once.
my question is how it would of be the best way to handle all of the 1000 clients??
a thread for each client isnt too much ?
|
|
|
|
|
You're right, creating a thread for each client won't scale. The best way to go about this is to use a threadpool. There is the System.Threading.ThreadPool[^] class provided by the .NET Framework. If you don't find it sufficient for your needs, there are also custom implementations of managed threadpools, a simple search in CP for "ThreadPool" should give you plenty of results.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
Isnt thread pool can proccess only 25 threads at a time? (max)
and 1000 active socket will create me a bottle neck
|
|
|
|
|
That limit is per processor, so if you have a dual processor machine, then it's 50 threads. If you want more threads than that, then it defeats the very purpose of having the threadpool. The basic assumption behind using a threadpool is you can distribute the work among a few precreated threads, so you have never have one thread idle and another doing all the work.
You can have a look here[^] if you want a custom implementation of Threadpools.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
If i understand right threadpool are good for threads which dont do much work
and alot of time under wait state
isnt it the exact opposite of my problem?
alot of active sockets ?
|
|
|
|
|
Again, what you say is true for the system provided threadpool thread. I'm saying this for the umpteenth time, you can always find custom implementations of it on the web.
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
|
|
|
|
|
I did something like this using remoting, delegates and events. It was pretty easy. I would avoid the mutithread, because it can become complex and it will slow you proformance with that many threads open.
|
|
|
|
|
I have created a a WinForm app. I (obviously) have Form1.design and
a Form1.cs file that I can see and access. I have then added a generic class (say-- class Foo) using the wizard in the class view.
Now here's the problem: for some reason the solution view "wipes out"
the Foo.cs file view and replaces it with a Foo.design view icon as well as creating a Foo Form. Why? I don't want ANY other Form in my project but Form1 and I wan't only the Foo.cs file in the solution explorer? please help thanks a lot......
|
|
|
|
|
I've never seen the problem before.
Are you absolutely sure you added a Class file to the project instead of another Form?
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Hello all
can any one tell me if it is possible to make a car animation in picture box with some background which is also a picture some gif or bmp.if some one can tell me this then it is highly appreciable.thanks
bhatti
|
|
|
|
|
You can manage this also in panel just overriding the OnPaint method. Using PaintEventArgs.Graphics draw background image and the car frame over it.
Use double-buffering to prevent flickering.
|
|
|
|
|
Hi All,
I have this peculiar requirement.....I have a windows application developed in C#. The main form of the application doesnt have a "Title bar" (this is as per the design requirement..)...
Now, whenever we do Alt+Tab, the associated "Icon" as well as the content of the "Titlebar" of any window is displayed in the popup that comes up....But in my case, I can see only the associated Icon, but not the "Title" (as there is no "Titlebar" in the first place) .
Any means by which I can display this info as well, without actually having the "Title" bar
|
|
|
|
|
The only way I can think to do this is to enable/disable the title bar on the form in the "LostFocus" and "GotFocus" events. This way when the form is not in focus, it has a title bar and can be tabbed to. Then when it gets tabbed to the title bar disappears before the user sees it. The only problem here is that when there are two applications on the window side by side, you could lose focus without actually covering up the app so the user may see the title bar every now and then.
|
|
|
|
|
I wonder if u can help me in solving the following problem:
I want to divide a number by 10 and get the result as the highest number.
Let me explain with following examples:
13/10 = 2 and
27/10 = 3
I am using Math.Ceiling to get the higher value, but the problem is that it only works for double value. I have the following code:
decimal weight = 20.1;
decimal MaxWeight = 20;
double weightInDouble = Convert.ToDouble(weight);
double PackageWeight = Convert.ToDouble(MaxWeight);
double NumberOfPackagesNeeded = Math.Ceiling(weightInDouble / PackageWeight);
However, the problem I am facing is that if the weight=20.1 and I convert it to double value, I get 40.2, and this would give me a wrong answer.
So how can I get the higher value when I divide two decimal values.
regards
|
|
|
|
|
Have you actually tried what you are saying here? Im probably not getting you right but calling Convert.ToDouble(someDecimalValue) doesn't give you a value which is doubled. It just converts a number in a decimal format into a double format (which means double precision floating point number). Except for some very slight rounding issues the value will not be changed.
|
|
|
|
|
I am using VS.net debugger to run through my code. And when I convert 20.1 to double, VS.net debugger shows the weightInDouble=40.2
I also get the wrong answer:
double NumberOfPackagesNeeded = Math.Ceiling(20.1/ 20);
Should give me 2... but currently I am getting 3
regards
|
|
|
|
|
Check it again. Following code outputs "2" twice:
decimal weight = (decimal)20.1;
decimal MaxWeight = 20;
double weightInDouble = Convert.ToDouble(weight);
double PackageWeight = Convert.ToDouble(MaxWeight);
double NumberOfPackagesNeeded = Math.Ceiling(weightInDouble / PackageWeight);
Console.WriteLine(NumberOfPackagesNeeded);
NumberOfPackagesNeeded = Math.Ceiling(20.1/ 20);
Console.WriteLine(NumberOfPackagesNeeded);
Note that I changed the first line of code from our original post. The way you posted it gives a compilation error because the compiler identifies 20.1 as a double value which cannot be implicitely casted to decimal. Thats why I had to insert an explicit cast.
|
|
|
|
|
my mistake my mistake my mistake
After re-checking my code, I realised that 40.2 is the correct amount. I am getting "weight" value from database and I was expecting to get 20.1 instead of 40.2. So when I got 40.2, I thought there was something wrong with my application code.
Anyway, thanks again
|
|
|
|
|
Hi,
Can someone please tell me how can I scroll an image?and how can I manipulate its size so that it's adjust it according to the monitor size of the user's monitor?
Thanks,
E.A.
|
|
|
|