jump to navigation

Visual Studio 2010 and C# v4.0 Technology Preview Presentation April 29, 2009

Posted by codinglifestyle in C#, Visual Studio 2010.
Tags: , , , ,
1 comment so far

This is an expansion on my previous post on Tech-Ed 2008 which I attended last November’s in Barcelona.  As a condition for attending I gave a talk to my company, Storm Technology.  I put a good amount of effort to the attached PowerPoint presentation for my talk.  The company has graciously allowed me to distribute it which is great because all the information is relevant and up to date.  If you are giving a similar presentation and/or want a template for a good place to start you are welcome to my slides.

https://codinglifestyle.files.wordpress.com/2009/04/storm_teched2008.pptx

Enjoy!

Advertisement

AfxGetMainWnd in C# June 27, 2007

Posted by codinglifestyle in C#, CodeProject, Winform.
Tags: , , , ,
add a comment

Back in the heady days of MFC men were men; toiling away in C++ and writing hundreds of lines to do things which are now ludicrously simple.  However, we had a trick up our sleeves which doesn’t exist in today’s plastic fantastic .NET:

AfxGetMainWnd() and AfxGetApp() were two fantastic macros we could exploit from nearly anywhere in our app to get a pointer to our main window or application, respectively.

Yesterday I was writing a quick client/server app.  The server was a WinForm tray application whose main form consists of a simple list to display status messages.  I wanted the thread listening for incoming traffic to update the status list.  I really missed AfxGetMainWnd() as I had a hard time finding a way to get a handle to my main window.  Because this was a tray app, which starts minimized, I was unable to use _FormMain.ActiveForm or Process.GetCurrentProcess().MainWindowHandle.  In fact, MainWindowHandle, was interesting as when I double-clicked the tray icon (opening the main window) the handle became valid and I could use it.  But the minute a minimized the window back to the tray the handle became null again.  So I was stuck with no reliable way of getting a handle to talk to my main window.

There may have been a better way, but this was a simple project and I wanted to move on quick.  I changed my main window to be a singleton, hiding the constructor and exposing an Instance variable which returned the one instance of the form.

 

To do this, lets look at the constructor:

 

private _FormMain()

{

InitializeComponent();

}

 

private static _FormMain m_Form = null;

public static _FormMain Instance

{

get

{

if (m_Form == null)

m_Form = new _FormMain();

return m_Form;

}

}

We then need to make a simple change in program.cs:

//Application.Run(new _FormMain());

Application.Run(_FormMain.Instance);

And lastly, to handle calls to from another thread:

// This delegate enables asynchronous calls from other threads

delegate void AddMessageCallback(string sMsg, Color c);

 

public void AddMessage(string sMsg, Color c)

{

if (_ListStatus.InvokeRequired)

{

AddMessageCallback amc = new AddMessageCallback(AddMessage);

this.Invoke(amc, new object[] { sMsg, c });

}

else

{

ListViewItem lvi = new ListViewItem(sMsg);

lvi.ForeColor = c;

_ListStatus.Items.Add(lvi);

_ListStatus.Refresh();

}

}

Note the delegate/invoke code used in AddMessage is straight from MSDN’s How to make thread-safe calls to Winform controls.

This way, I was able to simply call the following from anywhere in my code:

 


_FormMain.Instance.AddMessage(“Client has connected…”, Color.Green);