|
For default compilation of events for C# and other managed languages, the event itself is private. See my reply to Marc.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Why can't you just call EventName(this, EventArgs.Empty) , for example? Partly due to a language limitation, which is because of how C# (and others) compiles events by default.
Take the following example, compiled as a DLL:
using System;
public class Test
{
public event EventHandler Foo;
protected virtual void OnFoo(EventArgs e)
{
if (Foo != null)
Foo(this, e);
}
} Now let's look at the IL generated for this simple class following the event guidelines:
.class public auto ansi beforefieldinit Test
extends [mscorlib]System.Object
{
.field private class [mscorlib]System.EventHandler Foo
.method public hidebysig specialname instance void
add_Foo(class [mscorlib]System.EventHandler 'value') cil managed synchronized
{
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldfld class [mscorlib]System.EventHandler Test::Foo
IL_0007: ldarg.1
IL_0008: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
IL_000d: castclass [mscorlib]System.EventHandler
IL_0012: stfld class [mscorlib]System.EventHandler Test::Foo
IL_0017: ret
}
.method public hidebysig specialname instance void
remove_Foo(class [mscorlib]System.EventHandler 'value') cil managed synchronized
{
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldfld class [mscorlib]System.EventHandler Test::Foo
IL_0007: ldarg.1
IL_0008: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
IL_000d: castclass [mscorlib]System.EventHandler
IL_0012: stfld class [mscorlib]System.EventHandler Test::Foo
IL_0017: ret
}
.method family hidebysig newslot virtual
instance void OnFoo(class [mscorlib]System.EventArgs e) cil managed
{
.maxstack 3
IL_0000: ldarg.0
IL_0001: ldfld class [mscorlib]System.EventHandler Test::Foo
IL_0006: brfalse.s IL_0015
IL_0008: ldarg.0
IL_0009: ldfld class [mscorlib]System.EventHandler Test::Foo
IL_000e: ldarg.0
IL_000f: ldarg.1
IL_0010: callvirt instance void [mscorlib]System.EventHandler::Invoke(object,
class [mscorlib]System.EventArgs)
IL_0015: ret
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
.event [mscorlib]System.EventHandler Foo
{
.addon instance void Test::add_Foo(class [mscorlib]System.EventHandler)
.removeon instance void Test::remove_Foo(class [mscorlib]System.EventHandler)
}
} Notice that a private field Foo is defined as EventHandler . From a derived class, as you know, you can't access the private therefore you can't call Invoke on it, which invokes each of the combined delegates.
Some classes - like Windows Forms controls - store the EventHandler derivatives into the protected Control.Events , which you can get the combined delegate and invoke it yourself.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Heath Stewart wrote:
Partly due to a language limitation, which is because of how C# (and others) compiles events by default.
Is this a decision the compiler vendor can make, or is it part of the standard? Just curious.
And thank you very much for the response!
Marc
MyXaml
Advanced Unit Testing
YAPO
|
|
|
|
|
Good question, and it's one I'm not sure about off the top of my head (damn you, Marc! ). Unfortunately, I don't have the time too look it up, but if you'd like to it'd be great to know.
I doubt it's a language issue, though. If anything it may be a CLI guidelines or even a rule, but if you were to write the class in IL (personally, I enjoy such pain and anguish) you could define the field as public or family (IL's "protected"). I did so, changed the name of the field (so I could access it in lieu of the public .event definition), and re-assembled it with ilasm.exe with no problems. Compiling the following driver app compiled and ran just fine with the expected output:
using System;
class Test2 : Test
{
static void Main()
{
Test2 t = new Test2();
t.Foo += new EventHandler(t.Test_Foo);
if (t.FooEvent != null)
t.FooEvent(t, EventArgs.Empty);
}
private void Test_Foo(object sender, EventArgs e)
{
Console.WriteLine("Hello, world!");
}
}
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi Marc
Remember an event is just a limited delegate. Now if u dont mind losing the pretty event icons, you can just expose delegate fields in your class directly. The usage will be exactly the same (both are 'multicast'), except that delegates allows to be nulled and assigned directly, where events cant.
top secret Download xacc-ide 0.0.3 now! See some screenshots
|
|
|
|
|
How to get a number of row in column by using OleDbDataReader. thank
|
|
|
|
|
|
ahh sorry for my stupid question? I mean How do I get the number of rows. Thank.
|
|
|
|
|
Get the Count property of the DataTable.Rows property for the DataTable in the DataSet for which you want the count, like in the following example:
int count = dataSet1.Tables["MyTable"].Rows.Count; There is a lot of functionality defined for the DataSet class and related classes, so you'd best read the documentation[^], as well as Accessing Data with ADO.NET[^] in the .NET Framework SDK, which gives a great overview of ADO.NET as well as many examples, which are also included in some of the class library documetentation.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi
Does anyone knows how to Send a Hotkey using the WinApi?
I want to send CTRL-ALT-DELETE to an Remote Client.
I should use SendInput but I don't know how.
Can anyone help me????
Best Regards
|
|
|
|
|
You can't hook the remote keyboard, this has already been answered here[^].
|
|
|
|
|
You can't use SendInput on your machine to send keystrokes to a remote machine.
You CAN use it if the remote machine is running a server application that responds to request from a client application on your machine. You can put the SendInput code in the server app and execute it on some signal that you come up with and send using the client app.
But, then, Heath already told you this... If you need to figure out SendInput and C#, then Google for it! All you need to search for is "SendInput C#". Here[^], I've done it for you.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
I want get info from the Outlook Express inbox folder which is an .dbx-file. The problem is that some characters seem to be randomly converted to strange characters. Is it binary, unicode or what? How do I convert the .dbx file to plain text, like an .txt file.
/larbo204
www.nymax.nu
|
|
|
|
|
Yes it's binary. To store all that data in text would be terribly inefficient and impractical, do to look-up times and handling different text encodings.
The structure of the .dbx file is not public knowledge and can change at any time. If you want to export your mail then use the built-in export functionality from the File menu in OE, which has nothing to do with C# and is outside the scope of this forum.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hello,
I am trying to show, in a datagrid, a two level structure of <group> and then <company> as a child of <group>.
I can add a DataRelation between the two, but when displayed in a datagrid, when expanding the top level you are shown a link which when clicked shows a different table (the child table).
I would really like the child data to be shown in the same dataview as the parent data (indented). I have seen many controls for this in asp.net, but not for winforms. I just wondered if anyone has created, or knows how ro, create such a control.
Thanks in advance,
Richard
|
|
|
|
|
The .NET BCL (base class library) does not define such a control and to get the DataGrid to do so would be more work than it would probably be worth.
There are several third-pary libraries which offer such rich controls for an affordable price, like UltraGrid (or something like that) from Infragistics[^].
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Infragistics is a great software , but the things is , it makes it more difficult , esp to handle the events , controls..
If you have a solution in mind , and gonna use Infra , you should consider your solutions a few more times..
Well the choice depends on you , and I saw a lot of people having the same need..
"Please more controls for Winform DataGrid"
Complex controls , or simple and efficient controls ?
Thats depend on you..
|
|
|
|
|
Bahadir Cambel wrote:
Infragistics is a great software , but the things is , it makes it more difficult , esp to handle the events , controls..
What are you talking about? They implement the event guidelines and you don't have to implement handlers to get the functionality the original poster was talking about. None of the third-party controls in this area have required complex handlers. Implementing your own control from scratch would definitely be a lot more work in terms of man hours and resources costs than a royalty-free developer license for under a few hundred dollars.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi
i have a solution with 2 project.
a webservice project ,name it A.
a client for A ,name it B.
A has some classes.
until a few days ago A's classes was validating by B.
now i have added one another class to A.
B validates previous A's classes but B doesnt know A's new class.
even i wrote new class with same content of a previous classes but
doesnt happen anything and problem exists yet.
what should i do plz?
|
|
|
|
|
|
hi
i did it already but problem exists.
|
|
|
|
|
You should both update the reference , and the client interface to the webservice.
|
|
|
|
|
Hi!!!
I have a list of all active windows in my system, I can get their handles, the tittle af the applications, etc, but I want to know the kind of application it is. I mean.. if this window is open, I'd get the tittle, that is " The code Project - Free Source Code and Tutorials - Microsoft Internet Explorer".
Do you know if I could get only the application, that is "Microsoft Internet Explorer"?
I know in this case, it seems obvious 'cos I could take it from the tittle, but with other application is much difficult.
Thanks
|
|
|
|
|
Window titles do not define a class of windows. If you want to enumerate windows for a particular window class (applications typically define their own window classes, like Word always uses the window class "OpusApp" while Internet Explorer uses "IEFrame", which you can see from using Spy++ that ships with Visual Studio and the Platform SDK tools.
With that in mind, you can P/Invoke EnumWindows and then P/Invoke GetClassName to get the Window class name. An example follows:
using System;
using System.Runtime.InteropServices;
using System.Text;
class EnumWindowExample
{
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.Error.WriteLine("Error: Please specify a window class.");
Environment.Exit(1);
}
IntPtr ptr = IntPtr.Zero;
try
{
ptr = Marshal.StringToHGlobalAuto(args[0]);
EnumWindows(new EnumWindowsProc(Callback), ptr);
}
finally
{
if (ptr != IntPtr.Zero)
Marshal.FreeHGlobal(ptr);
}
}
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, [Out] StringBuilder lpClassName,
int nMaxCount);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString,
int nMaxCount);
delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
const int MAX_CLASS = 256;
const int MAX_TITLE = 256;
static bool Callback(IntPtr hwnd, IntPtr lParam)
{
StringBuilder windowClass = new StringBuilder(MAX_CLASS);
StringBuilder windowTitle;
string cls = Marshal.PtrToStringAuto(lParam);
if (GetClassName(hwnd, windowClass, MAX_CLASS) != 0)
{
if (string.Compare(windowClass.ToString(), cls, true) == 0)
{
windowTitle = new StringBuilder(MAX_TITLE);
if (GetWindowText(hwnd, windowTitle, MAX_TITLE) != 0)
Console.WriteLine(windowTitle.ToString());
}
}
return true;
}
} Just compile the app and pass a class name like "IEFrame" to get all the Internet Explorer windows (those started with iexplore.exe, mind you).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
If you're trying to determine what process owns a particular window, then Heath's excellent example is the way to go. The only caveat with that approach is that you'll have to know the class name(s) that a given application uses in order to map the window class to the application.
If, on the other hand, you're just trying to identify processes that are running on the machine, you can use the System.Diagnostics.Process class. This approach would allow you to identify all processes on the machine, including those that do not have windows.
<br />
using System;<br />
using System.Diagnostics;<br />
<br />
namespace EnumProcesses<br />
{<br />
class EnumProcsExample<br />
{<br />
[STAThread]<br />
static void Main(string[] args)<br />
{<br />
Console.WriteLine( "Enumerating processes..." );<br />
<br />
Process [] processes = Process.GetProcesses( );<br />
<br />
foreach ( Process process in processes )<br />
{<br />
Console.WriteLine( String.Format( "{0} : {1} ({2})", process.ProcessName, process.MainWindowTitle, process.MainWindowHandle ) );<br />
}<br />
<br />
Console.WriteLine( "Done." );<br />
Console.ReadLine( );<br />
<br />
<br />
}<br />
}<br />
}<br />
For the processes that do have windows, you can get the title and handle of the main window. You will not be able to get handles to all of the process's windows without some additional work, however. To do this, you could P/Invoke EnumThreadWindows to get all the non-child windows created by each thread in the process, and then you could P/Invoke EnumChildWindows for each of those windows.
If you need to be able to enumerate the windows for the process, let me know, and I'll throw together a sample for that.
Hope this helps,
PatrickShane
|
|
|
|
|