|
ke5in wrote:
Q1: How would I "register" the OnHereIam handler in a C# Program? (I read about AddMessageFilter in MSDN but its rather vague to me.)
You are better off overriding WndProc for this. AddMessageFilter should be the last option because of the overhead involved of calling the added message filters for *every* message passed to the UI thread, where-as WndProc only gets called for messages passed to that particular window.
The On* methods are called by the WndProc, not through any sort of magic but by putting something such as a switch statement in the WndProc and test for each message then calling the appropriate On* method.
ke5in wrote:
Q2: What would the "return" statement look like? I mean how do you "cast" LRESULT in C#?
The return type should be IntPtr.
ke5in wrote:
Q3: I guess if there is a way to register the OnHereIam message handler I won’t need to write a custom WndProc. But if I have too write one how is this usually done?
protected override void WndProc( ref Message m )
{
const int UWM_HERE_I_AM = 0x1234;
switch( m.Msg )
{
case UWM_HERE_I_AM:
m.Result = OnHereIAm( m.WParam, m.LParam );
return;
}
base.WndProc( ref m );
} Normally you would follow the event architecture that .NET already provides (event, delegate, and protected On* method for inheritors to override).
HTH,
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
I tried emailing this but just got a bounce-back in return:
> In C# I can create a class for a thread and get it running.
> But the thing that has me confused is the “event” which
> occurs in the application. How do I notify the thread that
> this “event” has occurred using “the event architecture that
> .NET already provides”?
Here is how I would set it up (ignore capitalization, I'm typing in outlook so it likes to 'correct' me). There are two different ways of doing this, the first is used if its just a notification that something happened ("I was clicked", "I finished processing the task you already know about", etc), the second is used if you need to supply some data to the listener.
First the notification method:
class MyThread : ....
{
public event EventHandler MyEvent;
protected virtual void OnMyEvent(EventArgs e)
{
FireMyEvent(e);
}
private void FireMyEvent(EventArgs e)
{
if( MyEvent != null )
{
MyEvent(this, e);
}
}
private void SomeCode()
{
SomeLengthyProcessing();
SomeMoreProcessing();
OnMyEvent(EventArgs.Empty);
EvenMoreProcessing();
}
} Now in the code that needs to receive that event:
.....
MyThread mt = new MyThread();
mt.MyEvent += new EventHandler(myMethodToExecuteWhenMyEventHappens);
.....
private void myMethodToExecuteWhenMyEventHappens(object sender, EventArgs e) {
}
In the cases where you have data to be returned you use the same pattern, but the type names change a bit
class MyEventEventArgs : EventArgs
{
private int myValue;
public MyEventEventArgs( int myValue )
{
this.myValue = myValue;
}
public int MyValue
{
get { return myValue; }
}
}
class MyThread : ....
{
public delegate void MyEventEventHandler(object sender, MyEventEventArgs e);
public event MyEventEventHandler MyEvent;
protected virtual void OnMyEvent(MyEventEventArgs e)
{
FireMyEvent(e);
}
private void FireMyEvent(MyEventEventArgs e)
{
if( MyEvent != null )
{
MyEvent(this, e);
}
}
private void SomeCode()
{
SomeLengthyProcessing();
SomeMoreProcessing();
MyEventEventArgs e = new MyEventEventArgs(42);
OnMyEvent(e);
EvenMoreProcessing();
}
} Now in the code that needs to receive that event:
.....
MyThread mt = new MyThread();
mt.MyEvent += new MyEventEventHandler(myMethodToExecuteWhenMyEventHappens);
.....
private void myMethodToExecuteWhenMyEventHappens(object sender, MyEventEventArgs e) {
int value = e.MyValue;
} A lot of this seems like its overkill, but once you have used the framework for a while you begin to appreciate this style of event handling (its possible to attach 100 listeners to an event, where as posting to a thread's message queue only notifys that thread).
HTH,
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
how can i create Wizards in C#? is it still by using property sheets and pages? or something else?
can somebody point me to the right direction or maybe share some code if wrote it already.
thanks
|
|
|
|
|
what i meant was wizard like application using C#, maybe by using form?
|
|
|
|
|
I created mine by using a combination of Forms and UserControls.
I think I'll clean the code up and post an article over this weekend
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
Ok, I am taking my first step into control development using C#. Actually I have not even created one with VB yet (my native language) so I guess I am a newbie all the way around as far as control making is concerned. I am having issues with two areas:
1) My control (to start simple) is nothing more than a label control placed upon a panel. I want to be able to set the text of the label control via a property. My code is as follows:
public override string Text
{
get
{
return lblInfoText.Text;
}
set
{
lblInfoText.Text = value;
}
}
This allows me to set the text of the control from the property list, but once I run the application the text is gone. I assume this is because nothing is persisiting the text that I have entered in to the ComponentInit area of the form code. How do I get that to happen?
2) Because I am deriving my control from a panel there are several properties that I get automaticialy, but I don't want to exspose all of them to the outside world because they don;t make sense in my control (IE: BackgroundImage, AllowDrop, Autoscroll*, etc...) How do I remove them from the property list? I assume that it is an attribute, but I am not sure which one. I have tried setting the browseable one to false and it dfoes not seem to work.
Thanks for any guidence that you can offer.
|
|
|
|
|
from MSDN : When you derive a component or control from a base component that has design-time attributes, your component inherits the design-time functionality of the base class. If the base functionality is adequate for your purposes, you do not have to reapply the attributes. However, you can always override attributes or apply additional attributes to the derived component. The following code fragment shows a custom control that overrides the Text property inherited from Control by overriding the BrowsableAttribute attribute applied in the base class.
public class MyControl : Control {
[Browsable(false)]
public override string Text {...}
...
}
|
|
|
|
|
So I have to override them just to set the browsable attribute to false?
UGH!
|
|
|
|
|
[
Browsable(false),
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public override string Text {
get {
return base.Text;
}
set {
base.Text = value;
}
}
And I swallow a small raisin.
|
|
|
|
|
Yahooooo!
Thank You, Thank You, Thank You, Thank You, Thank You, Thank You....
That was all the info I was looking for
Off into comtrol land I go
|
|
|
|
|
Oh, and be sure to apply .Net SP2 as well. Bugs I have had with the editor have vanished since then.
|
|
|
|
|
Okay, judging by some of the questions here, this should be a synch but I can't find the answer anywhere.
I've created my own .NET Component in C# with a nice event in it, ever so simple, no imagery involved, just a simple component (I guess like a timer). I've also created a test program as a seperate project in the same solution.
First of all, I kind of expected an easier way of including the component in the Toolbox than to browse for the DLL. Is there one?
Secondly, if I then drag the component into the form designer, it creates the icon at the bottom as I'd expect, but if I double-click on it, it does nothing. To create an event handler, I have to do it manually with
this.MyObject.MyEvent += new MyNamespace.MyEventHandler(this.MyObject_OnMyEvent);
I'm sure there must be an easy way of doing this.
Anyone?
Paul
|
|
|
|
|
Haven't played much with it, but it looks like the use of [...] attributes on top of classes allows to define default events. Especially [DefaultEvent(eventname)].
See MSDN doc for further details : .Net Framework / Programming with the .Net Framework / Developing components / Design-Time attributes for components.
What follows is an excerpt :
[DefaultEvent("CollectionChanged")]
public class MyCollection : BaseCollection {
private CollectionChangeEventHandler onCollectionChanged;
public event CollectionChangeEventHandler CollectionChanged {
add {
onCollectionChanged += value;
}
remove {
onCollectionChanged -= value;
}
}
}
Hey, that would be really worth a CP article.
|
|
|
|
|
That's what I'm looking for, thanks Stephane, works like a charm.
You're right that this would make a good article, in fact now I look at the System.ComponentModel Namesapce article in MSDN, there's a number of useful attributes that could make for one useful article.
But what would be even more useful is a comprehensive list of all Attributes, preferably grouped by both what you apply them to (in this case the class) and a general usefulness category (in this case events or components).
I've been all over MSDN and every other site I know looking for this and I was always convinced it would be an attribute.
If anyone knows of such a thing, please let me know.
For now, thanks again Stephane.
|
|
|
|
|
pdriley wrote:
First of all, I kind of expected an easier way of including the component in the Toolbox than to browse for the DLL. Is there one?
There is a key in the registry that contains a list of all the places that VS.NET will search for assemblies to show in that dialog:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
Thanks James.
Not sure this is actually easier, especially as I need to move this between PCs at times. However, it does go some way to explain how it all works.
Paul
|
|
|
|
|
I need to send a WM message to a thread. Is there a substitute for SendMessage? And, incidentally, is there a PostMessage equivalent?
Thanks,
-Keivn
|
|
|
|
|
if you want to send a message in c#, here is the way to declare ...
[DllImport("user32.dll",EntryPoint="SendMessage",ExactSpelling=false,SetLastError=true)]
private static extern int SendMessage(int hwnd,int wMsg,int wParam,int lParam);
[DllImport("user32.dll",,EntryPoint="PostMessage",ExactSpelling=false,SetLastError=true)]
private static extern int PostMessage(int hwnd,int wMsg,int wParam,int lParam);
Hope this helps..
Thanks
|
|
|
|
|
Cool, thanks. I was just wondering if there was some C# or .NET way of doing this. They seem to abstract nearly everything else but I guess abstracting this would be getting too far away from an OS/hardware neutral language.
Thanks for the info,
-Kevin
|
|
|
|
|
Agreed. That's the big trick (or lie, depending on the irony level) behind the DotNet framework. It is supposed to be interoperable, or even cross-platform and what people do is SendMessage or other things.
In articles such like these, the author uses a utility wrapper for a significant portion of the win32 API.
It looks like when you have to go through lower-level code, the uses of messages, notifications and so on is inevitable.
IMHO, MS is not to blame for disabling it entirely in C# (this is btw is almost impossible as the whole operating system is based on windows messaging). MS is to blame for providing an overridable WndProc(message) method for most C# UI controls, which indeed tends to make us keep the former approach.
What I would expect for DotNet 2.0 later in 2003 is a finished product, with a rich eventsubscriber-based mechanism that, especially when run on Windows, is exactly translated in lower layers as known windows messages and notifications. Or else provide richer API for most C# UI controls so that when we need to use owner drawing, we don't need to rely on WM_ stuff.
|
|
|
|
|
I'd agree with that prediction. MS already bit the bullet and included the Microsoft.Win32 namespace but all they included of any use is Registry handling (although that is such a nightmare when using the API in VB, having to fill out the strings for accepting the values, it's no surprise that it was a priority here).
I'm sure Windows Messaging will be the next thing they have to give in on, it's too fundamental, even if it is easy enough to import.
On the whole, I don't think people will see it as a break-down in the "multi-platform" thinking. If you want to write a multi-platform program for the mythical "other" platforms that will support a DotNet Framework, you stay away from the Microsoft Namespace; you're probably not going to want to access the registry or send any windows messages anyway.
But you've still got to be able to use the full Windows API readily if you feel the need and don't give a damn about other platforms. I'm sure the DotNet team will see this... eventually.
|
|
|
|
|
In a way, it could just be an extension of delegates, couldn't it? Currently delegates just become function calls, but you could, I guess, have different delegate classes with different implementations, sending windows messages instead? It's all just implementation detail...
Stuart Dootson
'Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p'
|
|
|
|
|
StephaneRodriguez wrote:
It is supposed to be interoperable, or even cross-platform
It *is* interoperable and cross-platform when you focus on the parts of the framework that hold that promise. Windows Forms, ADO.NET, ASP.NET among other technologies are not part of the CLI which is portion of the framework carrying that promise.
Other projects such as Mono are working on bringing over the non-CLI parts.
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|
Interoperable ? Not sure.
If we forget UI or other application layers, and go down to the simplest types such like "int" and "char", then if we refer to the MSDN documentation is is clearly said that :
- "int" is 32 bits : how does it cope with 64-bit oses ready this year?
- "char" is 16bits : how does it cope with the latest Unicode additions (I have read somewhere that 30 000 symbols have been added lately) ?
I don't know if the documentation showed this mapping just to give a snapshot reference while remaining essentially dynamical, or if it is hardcoded once for all.
In the second case, C# is just C without pointers. There is no more interoperability in it.
To add to the irony, I have to argue that WindowsCE is with the .Net framework not even part of their strategy, as (as for what I have seen so far) no method implementation targets this platform.
In fact, what MS calls interoperable is on the one hand interoperable across their own Windows platforms (not between Sun,HP,S/390,...). On the other hand, they actually cannot stand this either : VisualStudio.Net does not target PDAs or other devices. The Mobile internet toolkit looks like an application layer, not a framework layer.
AFAIK, I want MS to be able to ensure developers that at least a program developed targeting for instance WIN2000 can actually be run on any WIN2000 consumer machine.
This sounds stupid, but why should I spend time developing software that someone else will not be able to run ?
This happen to have been a failure for many of MS APIs, including DirectX.
Regards
|
|
|
|
|
StephaneRodriguez wrote:
If we forget UI or other application layers, and go down to the simplest types such like "int" and "char", then if we refer to the MSDN documentation is is clearly said that :
- "int" is 32 bits : how does it cope with 64-bit oses ready this year?
int will always be 32-bit in .NET; the full typename is System.Int32. In cases where you need a scalable value such as for pointers use IntPtr as that is what it is used for. On 32-bit platforms IntPtr will be 4 bytes and on 64-bit platforms it will be 8 bytes.
If you need a 64 bit integer use C#s "long" or System.Int64.
StephaneRodriguez wrote:
- "char" is 16bits : how does it cope with the latest Unicode additions (I have read somewhere that 30 000 symbols have been added lately) ?
Good point, and I have no idea; I assume we'll be stuck in the same situation as before and use codepages.
StephaneRodriguez wrote:
I have to argue that WindowsCE is with the .NET framework not even part of their strategy, as (as for what I have seen so far) no method implementation targets this platform.
Its coming, last I knew the Compact Framework was still in beta. Quite a few people got to play with it back in the early Beta phases and they liked it. Unfortunately I only have a Palm 100 so I didn't get to have any fun
Smart Device Extensions and .NET Compact Framework Beta 1[^]
StephaneRodriguez wrote:
The Mobile internet toolkit looks like an application layer, not a framework layer.
It provides server controls for ASP.NET which should render correctly given the devices support. Whether that is an application layer or a framework layer could be debated because it behaves as both in places.
StephaneRodriguez wrote:
In fact, what MS calls interoperable is on the one hand interoperable across their own Windows platforms (not between Sun,HP,S/390,...).
Aside from not having an implementation of the CLI, what would stop a .NET console program from working on Sun, HP, S/390, etc? The CLI is the only part that Microsoft has said would be open for porting, the other technologies are more or less tied to Windows and kin thus it wouldn't make much sense to port them.
Of course MS is pushing the usage of Windows Forms and non-CLI portions of .NET, just like they've pushed the use of COM. Unlike COM though, we're seeing other implementations being produced.
StephaneRodriguez wrote:
This happen to have been a failure for many of MS APIs, including DirectX.
I would hardly call DirectX a failure; you'll have a hard time finding any retail game released in the last 3 years that doesn't use at least some part of DirectX. Keep in mind that DirectX started when the developers of Office saw the cool things the game SDK had and wanted to use some of those in Office.
James
"And we are all men; apart from the females." - Colin Davies
|
|
|
|
|