Quantcast

Maximum PC

It is currently Tue Nov 25, 2014 7:33 pm

All times are UTC - 8 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: .NET / C# / Win forms / ASP.NET / WCF / ETC Tips & Trick
PostPosted: Wed May 28, 2008 8:22 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Since I started a new job, as a C# Windows developer, I decided that as I find nifty little things that help me work harder/better/faster/stronger (nice!) that I would post them here. I am sure it will be ugly, but a resource none the less. I am sure eventually I will clean things up.

I will keep this first post updated as best I can. Feel free to add any tips you all discover that might help me, yourself at a later date, or anybody in general.

Navigation / Quick Links


Last edited by CrashTECH on Tue Sep 09, 2008 9:37 am, edited 4 times in total.

Top
  Profile  
 
 Post subject:
PostPosted: Wed May 28, 2008 8:24 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Auto-Magically Create a "busy" cursor.

I found this while trying to implment a client request... his code wasn't formatted well (due to the website encoding probably). The original post can be found here:

http://www.myownshit.dk/2006/07/31/auto ... plication/

I cleaned up the tabs in the library (I will eventually link to a cs file).
Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace AutoWaitCursor
{
    #region README
    ///
    /// This static utility class can be used to automatically show a wait cursor when the application
    /// is busy (ie not responding to user input). The class automatically monitors the application
    /// state, removing the need for manually changing the cursor.
    ///
    ///
    /// To use, simply insert the following line in your Application startup code
    ///
    ///  private void Form1_Load(object sender, System.EventArgs e)
    ///  {
    ///   AutoWaitCursor.Cursor = Cursors.WaitCursor;
    ///   AutoWaitCursor.Delay = new TimeSpan(0, 0, 0, 0, 25);
    ///   // Set the window handle to the handle of the main form in your application
    ///   AutoWaitCursor.MainWindowHandle = this.Handle;
    ///   AutoWaitCursor.Start();
    ///  }
    ///
    /// This installs changes to cursor after 100ms of blocking work (ie. work carried out on the main application thread).
    ///
    /// Note, the above code GLOBALLY replaces the following:
    ///
    /// public void DoWork()
    /// {
    ///  try
    ///  {
    ///   Screen.Cursor = Cursors.Wait;
    ///   GetResultsFromDatabase();
    ///  }
    ///  finally
    ///  {
    ///   Screen.Cursor = Cursors.Default;
    ///  }
    /// }
    ///
    #endregion

    [DebuggerStepThrough()]
    public class AutoWaitCursor
    {
        #region Member Variables
        //The application state monitor class (which monitors the application busy status).
        private static ApplicationStateMonitor _appStateMonitor = new ApplicationStateMonitor(Cursors.WaitCursor, DEFAULT_DELAY);
        private static readonly TimeSpan DEFAULT_DELAY = new TimeSpan(0, 0, 0, 0, 25);
        #endregion

        #region Constructors
        private AutoWaitCursor()
        {
            // Intentionally blank
        }
        #endregion

        #region Public Static Properties
        // Returns the amount of time the application has been idle.
        public TimeSpan ApplicationIdleTime
        {
            get { return _appStateMonitor.ApplicationIdleTime; }
        }

        //Returns true if the auto wait cursor has been started.
        public static bool IsStarted
        {
            get { return _appStateMonitor.IsStarted; }
        }

        //Gets or sets the Cursor to use during Application busy periods.
        public static Cursor Cursor
        {
            get { return _appStateMonitor.Cursor; }
            set { _appStateMonitor.Cursor = value; }
        }

        // Enables or disables wait cursor
        public static bool Enabled
        {
            get { return _appStateMonitor.Enabled; }
            set { _appStateMonitor.Enabled = value; }
        }

        // Gets or sets the period of Time to wait before showing the WaitCursor whilst Application is working
        public static TimeSpan Delay
        {
            get { return _appStateMonitor.Delay; }
            set { _appStateMonitor.Delay = value; }
        }

        // Gets or sets the main window handle of the application (ie the handle of an MDI form).
        // This is the window handle monitored to detect when the application becomes busy.
        public static IntPtr MainWindowHandle
        {
            get { return _appStateMonitor.MainWindowHandle; }
            set { _appStateMonitor.MainWindowHandle = value; }
        }
        #endregion

        #region Public Methods
        // Starts the auto wait cursor monitoring the application.
        public static void Start() { _appStateMonitor.Start(); }

        // Stops the auto wait cursor monitoring the application.
        public static void Stop() { _appStateMonitor.Stop(); }
        #endregion

        #region Private Class ApplicationStateMonitor
        // Private class that monitors the state of the application and automatically
        // changes the cursor accordingly.
        private class ApplicationStateMonitor : IDisposable
        {
            #region Member Variables
            // The time the application became inactive.
            private DateTime _inactiveStart = DateTime.Now;
            // If the monitor has been started.
            private bool _isStarted = false;

            // Delay to wait before calling back
            private TimeSpan _delay;

            // The windows handle to the main process window.
            private IntPtr _mainWindowHandle = IntPtr.Zero;

            // Thread to perform the wait and callback
            private Thread _callbackThread = null;

            // Stores if the class has been disposed of.
            private bool _isDisposed = false;

            // Stores if the class is enabled or not.
            private bool _enabled = true;

            // GUI Thread Id .
            private uint _mainThreadId;

            // Callback Thread Id.
            private uint _callbackThreadId;

            // Stores the old cursor.
            private Cursor _oldCursor;

            // Stores the new cursor.
            private Cursor _waitCursor;
            #endregion

            #region PInvokes

            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool SendMessageTimeout(IntPtr hWnd, int Msg, int wParam, string lParam, int fuFlags, int uTimeout, out int lpdwResult);

            [DllImport("USER32.DLL")]
            private static extern uint AttachThreadInput(uint attachTo, uint attachFrom, bool attach);

            [DllImport("KERNEL32.DLL")]
            private static extern uint GetCurrentThreadId();

            private const int SMTO_NORMAL = 0x0000;
            private const int SMTO_BLOCK = 0x0001;
            private const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;

            #endregion

            #region Constructors
            // Default member initialising Constructor
            // The wait cursor to use.
            // The delay before setting the cursor to the wait cursor.

            // Constructor is called from (what is treated as) the main thread
            public ApplicationStateMonitor(Cursor waitCursor, TimeSpan delay)
            {
                _mainThreadId = GetCurrentThreadId();
                _delay = delay;
                _waitCursor = waitCursor;

                // Gracefully shuts down the state monitor
                Application.ThreadExit += new EventHandler(_OnApplicationThreadExit);
            }
            #endregion

            #region IDisposable
            // On Disposal terminates the Thread, calls Finish (on thread) if Start has been called
            public void Dispose()
            {
                if (_isDisposed) { return; }

                // Kills the Thread loop
                _isDisposed = true;
            }

            #endregion IDisposable

            #region Public Methods
            // Starts the application state monitor.
            public void Start()
            {
                if (!_isStarted)
                {
                    _isStarted = true;
                    this._CreateMonitorThread();
                }
            }

            // Stops the application state monitor.
            public void Stop()
            {
                if (_isStarted)
                {
                    _isStarted = false;
                }
            }

            // Set the Cursor to wait.
            public void SetWaitCursor()
            {
                // Start is called in a new Thread, grab the new Thread Id so
                // we can attach to Main thread’s input
                _callbackThreadId = GetCurrentThreadId();

                // Have to call this before calling Cursor.Current
                AttachThreadInput(_callbackThreadId, _mainThreadId, true);

                _oldCursor = Cursor.Current;
                Cursor.Current = _waitCursor;
            }

            // Finish showing the Cursor (switch back to previous Cursor)
            public void RestoreCursor()
            {
                // Restore the cursor
                Cursor.Current = _oldCursor;
                // Detach from Main thread input
                AttachThreadInput(_callbackThreadId, _mainThreadId, false);
            }

            // Enable/Disable the call to Start (note, once Start is called it *always* calls the paired Finish)
            public bool Enabled
            {
                get { return _enabled; }
                set { _enabled = value; }
            }

            /// Gets or sets the period of Time to wait before calling the Start method
            public TimeSpan Delay
            {
                get { return _delay; }
                set { _delay = value; }
            }

            #endregion

            #region Public Properties
            // Returns true if the auto wait cursor has been started.
            public bool IsStarted
            {
                get { return _isStarted; }
            }

            // Gets or sets the main window handle of the application (ie the handle of an MDI form).
            // This is the window handle monitored to detect when the application becomes busy.
            public IntPtr MainWindowHandle
            {
                get { return _mainWindowHandle; }
                set { _mainWindowHandle = value; }
            }

            // Gets or sets the Cursor to show
            public Cursor Cursor
            {
                get { return _waitCursor; }
                set { _waitCursor = value; }
            }

            // Returns the amount of time the application has been idle.
            public TimeSpan ApplicationIdleTime
            {
                get { return DateTime.Now.Subtract(_inactiveStart); }
            }

            #endregion

            #region Private Methods
            // Prepares the class creating a Thread that monitors the main application state.
            private void _CreateMonitorThread()
            {
                // Create the monitor thread
                _callbackThread = new Thread(new ThreadStart(_ThreadCallbackLoop));
                _callbackThread.Name = "AutoWaitCursorCallback";
                _callbackThread.IsBackground = true;
                // Start the thread
                _callbackThread.Start();
            }

            // Thread callback method.
            // Loops calling SetWaitCursor and RestoreCursor until Disposed.
            private void _ThreadCallbackLoop()
            {
                try
                {
                    do
                    {
                        if (!_enabled || _mainWindowHandle == IntPtr.Zero)
                        {
                            // Just sleep
                            Thread.Sleep(_delay);
                        }
                        else
                        {
                            // Wait for start
                            if (_IsApplicationBusy(_delay, _mainWindowHandle))
                            {
                                try
                                {
                                    this.SetWaitCursor();
                                    _WaitForIdle();
                                }
                                finally
                                {
                                    // Always calls Finish (even if we are Disabled)
                                    this.RestoreCursor();
                                    // Store the time the application became inactive
                                    _inactiveStart = DateTime.Now;
                                }
                            }
                            else
                            {
                                // Wait before checking again
                                Thread.Sleep(25);
                            }
                        }
                    } while (!_isDisposed && _isStarted);
                }
                catch (ThreadAbortException)
                {
                    // The thread is being aborted, just reset the abort and exit gracefully
                    Thread.ResetAbort();
                }
            }

            // Blocks until the application responds to a test message.
            // If the application doesn’t respond with the timespan, will return false,
            // else returns true.
            private bool _IsApplicationBusy(TimeSpan delay, IntPtr windowHandle)
            {
                const int INFINITE = Int32.MaxValue;
                const int WM_NULL = 0;
                int result = 0;
                bool success;

                // See if the application is responding
                if (delay == TimeSpan.MaxValue)
                {
                    success = SendMessageTimeout(windowHandle, WM_NULL, 0, null,
                    SMTO_BLOCK, INFINITE, out result);
                }
                else
                {
                    success = SendMessageTimeout(windowHandle, WM_NULL, 0, null,
                    SMTO_BLOCK, System.Convert.ToInt32(delay.TotalMilliseconds), out result);
                }

                if (result != 0)
                {
                    return true;
                }

                return false;
            }

            // Waits for the ResetEvent (set by Dispose and Reset),
            // since Start has been called we *have* to call RestoreCursor once the thread is idle again.
            private void _WaitForIdle()
            {
                // Wait indefinately until the application is idle
                _IsApplicationBusy(TimeSpan.MaxValue, _mainWindowHandle);
            }

            // The application is closing, shut the state monitor down.
            private void _OnApplicationThreadExit(object sender, EventArgs e)
            {
                this.Dispose();
            }

            #endregion
        }
        #endregion
    }
}


Top
  Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 8:09 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
This is more of a general suggestion... and it is helpful even if you are not an enterprise or business developer.

Use some sort of source/code control and revisioning. Subversion is easy to use and set up, and works well within windows. Visual Source Safe integrates with Visual Studio very nicely.

At the very least, set up a task (Windows) or a cron job (Linux) that makes periodical backups of your code. Source code is small, it is just text. There is zero reason why you couldn't have 2-3 backups during the day, and then a daily archive.

I just had an instance happen this AM where I wish I had a backup of the code I wrote a couple days ago. I accidentally blew away some changes (although they were small and I was going to change the code anyway) I made last week.


Top
  Profile  
 
 Post subject:
PostPosted: Tue Jun 10, 2008 2:26 pm 
Million Club - 5 Plus*
Million Club - 5 Plus*
User avatar

Joined: Sun Sep 12, 2004 6:37 pm
Posts: 4745
Location: In the monkey's litterbox
ankhsvn is nice to use ;) ( http://ankhsvn.open.collab.net/ )

Also, have some sort of merger that works well. I use kdiff3, others may work well too. Sometimes CVS/SVN merging just doesn't cut it.


Top
  Profile  
 
 Post subject:
PostPosted: Tue Jul 01, 2008 4:07 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Expand / Collapse a region in Visual Studio

Quote:
As a developer you are much more faster, if you avoid mouse usage. For this there are a lot of shortcuts provided by Visual Studio 2005. As I use regions to arrange my classes, it is usefull to know about the shortcut to collapse and expand regions. Here is it:

CTRL+M CTRL+M


List of keyboard shortcuts for Visual Studio 2005


Top
  Profile  
 
 Post subject:
PostPosted: Thu Jul 24, 2008 11:58 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Find Stored Proceedures that have been created or modified in the past XX days:

For MSSQL 2000
Code:
SELECT name, type
    FROM sysobjects
    WHERE type = 'P'
        AND (DATEDIFF(D,refdate, GETDATE()) < XX
      OR DATEDIFF(D,crdate, GETDATE()) < XX)


For MSSQL 2005
Code:
SELECT name, type
    FROM sys.objects
    WHERE type = 'P'
        AND (DATEDIFF(D,modify_date, GETDATE()) < XX
      OR DATEDIFF(D,create_date, GETDATE()) < XX)


Top
  Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 7:24 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Combating flicker in Windows forms:
I recently switched development machines and I was seeing some really slow redering / paint times for the forms on the screen. At first I thought it was really strange because my new machine was much faster. I have spent the better part of the AM trying to figure it out.

I found this:
Quote:
In addition, The quick and dirty way to avoid most flicker is to use a
transparency key. Pick a color that won't affect your program such as lime
green, or some other ugly color that is not used by anything on your form.

The reason a form will sometimes flicker, often has to do with a bug in
WinForms and how it deals with transparent windows. WinForms is in fact
just a wrapper to the Windows API. When dealing with opacity, WinForms will
use a Windows API to convert your form to what is known as a layered window.


Double Buffering would also work (setting the forms DoubleBuffered property to true) although I am not sure it is the ideal case. Especially if you are trying to keep your memory footprint as low as possible.

Related URIs


Top
  Profile  
 
 Post subject:
PostPosted: Tue Sep 09, 2008 9:35 am 
SON OF A GUN
SON OF A GUN
User avatar

Joined: Mon Nov 01, 2004 5:41 am
Posts: 11605
Tip: "truncate" all tables with a given prefix:
Purpose: You have a collection of tables with the same prefix, and you need to delete all of the data in the tables.

I needed to do this. I have a case where I have some "static data" that gets synchronized between a few places. However, if the data gets wonky, sometimes things don't sync correctly. I have a set of staging tables tables and then application tables. There is a job that clears the stage tables before the data is copied in and timestamped. The app tables are then compared for differences. I wanted to start with a clean slate.

Truncate won't work, because there are foreign key relationships. Using this procedure in this fashion won't work properly either. However, when I found this example, I modified it to delete from each table rather than drop, etc.

Code:
DECLARE @ParentName varchar(256)
   DECLARE cr1 CURSOR FOR
    (
        SELECT [name]
        FROM sysobjects
        WHERE [name] LIKE 'TBLPREFIX_' + '%'
    )

    OPEN cr1
    FETCH FROM cr1 INTO @ParentName
    WHILE (@@fetch_status = 0)
    BEGIN
        EXEC ('DELETE FROM ' + @ParentName)
        FETCH NEXT FROM cr1 INTO @ParentName
    END
    CLOSE cr1
    DEALLOCATE cr1


Top
  Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 8 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

© 2014 Future US, Inc. All rights reserved.