Start a WinForm Hidden June 18, 2009
Posted by codinglifestyle in CodeProject, Winform.Tags: BackgroundWorker, hidden, threads, visible, Winform
add a comment
- In the designer, set your window Opacity to 0%
- In the constructor, pass in a boolean to indicate if the window is displayed.
- In the function body, add this line:
Opacity = bVisible ? 100 : 0;
AfxGetMainWnd in C# June 27, 2007
Posted by codinglifestyle in C#, CodeProject, Winform.Tags: AfxGetApp, AfxGetMainWnd, C#, singleton, Winform
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);
CWaitCursor for WinForms September 1, 2006
Posted by codinglifestyle in C#, Winform.Tags: CWaitCursor, IDisposable, wait cursor, Winform
add a comment
There is no doubt, developing Windows applications in .NET is miles easier than in the bad old days of MFC. However, there are times when MFC got it right and I found one of them this week. MFC had a handy class called CWaitCursor. You simply instantiated a local variable which would change the cursor to the wait icon. When the local variable went out of scope, the cursor changed back. I couldn’t find this functionality in .NET, but it was simple enough to duplicate:
internal class CWaitCursor : IDisposable
{
private Form m_Form;
public CWaitCursor(Form form)
{
m_Form = form;
m_Form.Cursor = Cursors.WaitCursor;
}
public void Dispose()
{
m_Form.Cursor = Cursors.Default;
}
}
To use in your form create a local instance and pass the this pointer. The using can be used to guarantee an immediate call to Dispose() like so:
using (new CWaitCursor(this))
{
…
}
Exposing C# controls as Active-X and the effects on developing with the download cache January 5, 2006
Posted by codinglifestyle in C#, Javascript, Winform.Tags: active-x, control, GAC, Javascript, Winform
add a comment
A C# assembly can be easily exposed as an Active-X control using the object tag like so:
<OBJECT id=”Bob” classid=”url to assembly#full name of control></OBJECT>
So for example my assembly is located in a virtual directory on server VM2003S2:88 called MyObject. MyObject has a namespace of Chris.ActiveX.Controls and the class is MyControl. My object tag would be: http://vm2003s2:88/myobject.dll#chris.activex.controls.mycontrol
This complete I can now use javascript to talk to “Bob” via MyControl’s public methods. This is all well and good however you may experience frustration in seeing your updates during development.
The assembly is automatically pulled down to the download cache which is located in c:\windows\assembly\downloads on Win2003. Unfortunately, its not smart enough to read version strings and realize a newer copy is available on the server. Therefore you must clear this cache using:
gacutil /cdl
But that’s not all! A copy is also made in your temporary internet files. You won’t be able to simply delete it using del from the post-build event as Window’s treats the directory as special. So either write a small program utilizing the API to delete your assembly from the cache or use one of the miriad of privacy utilities to clean this for you. I found CleanUp! which can be quietly executed from the command line and added to my post build event. The result is the assembly is pulled every time (on the development machine) so you see your changes with each build.
Here is a good example explaining Embedded Windows User Controls into Internet Explorer:
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=187