Tuesday, May 17, 2011

Synchronized RichTextBox objects (or how to scroll 2 RichTextBox objects together)

In my previous posts I have described, how to create synchronized (or linked) ListBox and ListView objects. Now I continue in investigation in this area and I have found another interesting example which describes synchronization of two RichTextBox objects. First step is to create class which derives from RichTextBox class.
public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTextBox
{
    public event vScrollEventHandler vScroll;
    public delegate void vScrollEventHandler(System.Windows.Forms.Message message);

    public const int WM_VSCROLL = 0x115;

    protected override void WndProc(ref System.Windows.Forms.Message msg)
    {
        if (msg.Msg == WM_VSCROLL)
        {
            if (vScroll != null)
            {
                vScroll(msg);
            }
        }
        base.WndProc(ref msg);
    }

    public void PubWndProc(ref System.Windows.Forms.Message msg)
    {
        base.WndProc(ref msg);
    }
}
I have created two SynchronizedScrollRichTextBox controls and placed them on the form. Then I have added following code (vScroll event):
private void synchronizedScrollRichTextBox1_vScroll(Message message)
{
    message.HWnd = synchronizedScrollRichTextBox2.Handle;
    synchronizedScrollRichTextBox2.PubWndProc(ref message);
}
Here you can find original post.

Monday, May 16, 2011

Synchronized ListView objects (or how to scroll 2 ListView objects together)

In my previous post I have described how to synchronize two ListBox objects. Here I will show, how to synchronize two ListView objects.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace SyncLists
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.listView1.View = View.Details;
            this.listView2.View = View.Details;
            for (int j = 0; j < 10; j++)
            {
                this.listView1.Columns.Add("c" + j.ToString());
                this.listView2.Columns.Add("c" + j.ToString());
            }
            for (int j = 0; j < 300; j++)
            {
                ListViewItem item = new ListViewItem("item" + j.ToString());
                for (int k = 1; k < 10; k++)
                {
                    item.SubItems.Add("sub item" + k.ToString());
                }
                this.listView1.Items.Add(item);
                this.listView2.Items.Add(item.Clone() as ListViewItem);
            }

            this.listView1.Scroll += new ListViewEx.ScrollHandler(listView1_Scroll);
        }

        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll")]
        static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

        private const int WM_HSCROLL = 0x114;
        private const int WM_VSCROLL = 0x115;
        private const int SBS_HORZ = 0;
        private const int SBS_VERT = 1;

        void listView1_Scroll(object sender, MyScrollEventArgs e)
        {
            ListViewEx listVw = sender as ListViewEx;

            Int16 hi = (Int16)((int)e.WParam >> 16);//position
            Int16 lo = (Int16)e.WParam;//scroll type

            if (e.Orientation == ScrollOrientation.VerticalScroll)
            {
                if (lo == 5) //SB_THUMBTRACK
                {
                    if (SetScrollPos(this.listView2.Handle, SBS_VERT, hi, true) != 0)
                    {
                        SendMessage(this.listView2.Handle, WM_VSCROLL,
                          (IntPtr)(4 + 0x10000 * hi), IntPtr.Zero);
                    }
                }
                else
                {
                    SendMessage(this.listView2.Handle, WM_VSCROLL, e.WParam, IntPtr.Zero);
                }
            }
            if (e.Orientation == ScrollOrientation.HorizontalScroll)
            {
                if (lo == 5)//SB_THUMBTRACK
                {
                    SetScrollPos(this.listView2.Handle, SBS_HORZ, hi, true);
                    SendMessage(this.listView2.Handle, WM_HSCROLL,
                       (IntPtr)(4 + 0x10000 * hi), IntPtr.Zero);
                }
                else
                {
                    SendMessage(this.listView2.Handle, WM_HSCROLL, e.WParam, IntPtr.Zero);
                }
            }
        }

    }

    public class ListViewEx : ListView
    {
        public delegate void ScrollHandler(object sender, MyScrollEventArgs e);
        public event ScrollHandler Scroll;
        public void OnScroll(MyScrollEventArgs e)
        {
            if (Scroll != null)
            {
                Scroll(this, e);
            }
        }

        private const int WM_HSCROLL = 0x114;
        private const int WM_VSCROLL = 0x115;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_VSCROLL)
            {
                MyScrollEventArgs e = new MyScrollEventArgs();
                e.WParam = m.WParam;
                e.Orientation = ScrollOrientation.VerticalScroll;
                OnScroll(e);
            }
            if (m.Msg == WM_HSCROLL)
            {
                MyScrollEventArgs e = new MyScrollEventArgs();
                e.WParam = m.WParam;
                e.Orientation = ScrollOrientation.HorizontalScroll;
                OnScroll(e);
            }
            base.WndProc(ref m);
        }
    }

    public class MyScrollEventArgs : EventArgs
    {
        private ScrollOrientation orientation;
        private IntPtr wParam;

        public IntPtr WParam
        {
            get { return wParam; }
            set { wParam = value; }
        }

        public ScrollOrientation Orientation
        {
            get { return orientation; }
            set { orientation = value; }
        }
    }
}

Synchronized ListBox objects (or how to scroll 2 ListBox objects together)

Before couple of days I had a task where I must synchronize two ListBox objects. I have fount out, that ListBox object doesn't have any property which allow to accomplish this. After a few hours of googling I found code of class that inherited from ListBox class. Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace SyncLists
{
    class SyncListBox : System.Windows.Forms.ListBox
    {
        [Category("Action")]

        private const int WM_HSCROLL = 0x114;
        private const int WM_VSCROLL = 0x115;

        public event ScrollEventHandler OnHorizontalScroll;
        public event ScrollEventHandler OnVerticalScroll;


        private const int SB_LINEUP = 0;
        private const int SB_LINELEFT = 0;
        private const int SB_LINEDOWN = 1;
        private const int SB_LINERIGHT = 1;
        private const int SB_PAGEUP = 2;
        private const int SB_PAGELEFT = 2;
        private const int SB_PAGEDOWN = 3;
        private const int SB_PAGERIGHT = 3;
        private const int SB_THUMBPOSITION = 4;
        private const int SB_THUMBTRACK = 5;
        private const int SB_PAGETOP = 6;
        private const int SB_LEFT = 6;
        private const int SB_PAGEBOTTOM = 7;
        private const int SB_RIGHT = 7;
        private const int SB_ENDSCROLL = 8;

        private const int SIF_TRACKPOS = 0x10;
        private const int SIF_RANGE = 0x1;
        private const int SIF_POS = 0x4;
        private const int SIF_PAGE = 0x2;
        private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;

        [DllImport("user32.dll", SetLastError = true)]
        private static extern int GetScrollInfo(
        IntPtr hWnd, int n, ref ScrollInfoStruct lpScrollInfo);


        private struct ScrollInfoStruct
        {
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;
        }

        protected override void WndProc(ref System.Windows.Forms.Message msg)
        {
            if (msg.Msg == WM_HSCROLL)
            {
                if (OnHorizontalScroll != null)
                {
                    ScrollInfoStruct si = new ScrollInfoStruct();
                    si.fMask = SIF_ALL;
                    si.cbSize = Marshal.SizeOf(si);
                    GetScrollInfo(msg.HWnd, 0, ref si);

                    if (msg.WParam.ToInt32() == SB_ENDSCROLL)
                    {
                        ScrollEventArgs sargs = new ScrollEventArgs(
                        ScrollEventType.EndScroll,
                        si.nPos);
                        OnHorizontalScroll(this, sargs);
                    }
                }
            }
            if (msg.Msg == WM_VSCROLL)
            {
                if (OnVerticalScroll != null)
                {
                    ScrollInfoStruct si = new ScrollInfoStruct();
                    si.fMask = SIF_ALL;
                    si.cbSize = Marshal.SizeOf(si);
                    GetScrollInfo(msg.HWnd, 0, ref si);

                    if (msg.WParam.ToInt32() == SB_ENDSCROLL)
                    {
                        ScrollEventArgs sargs = new ScrollEventArgs(
                        ScrollEventType.EndScroll,
                        si.nPos);
                        OnVerticalScroll(this, sargs);
                    }
                }
            }
            base.WndProc(ref msg);
        }


        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // scrolled
            // 
            this.Size = new System.Drawing.Size(120, 95);
            this.ResumeLayout(false);
        }
    }
}

add two SyncListBox objects on the form and add following code:

private void syncListView2_OnVerticalScroll(object sender, ScrollEventArgs e)
{
    syncListView1.TopIndex = syncListView2.TopIndex;
}

private void syncListView1_OnVerticalScroll(object sender, ScrollEventArgs e)
{
    syncListView2.TopIndex = syncListView1.TopIndex;
}

Sunday, April 24, 2011

T-SQL - Find which Object resides in which FileGroup

Select Distinct OBJECT_NAME(SI.object_id) AS ObjectName
,OBJECTPROPERTYEX(SI.object_id,'BaseType') AS ObjectType
,FG.Name AS FileGroupName
from sys.indexes SI , sys.filegroups FG
where SI.data_space_id = FG.data_space_id
Order by ObjectName

Friday, February 18, 2011

Measure execution time in C#

Sometimes developers need to measure execution time of task. This methodics could be useful when is important to compare two or more approaches and choose the best. .Net Framework contains Stopwatch class that can measure elapsed time for one interval, or total elapsed time across multiple intervals.
For more information navigate to: Stopwatch Class.

Following example demonstrates how to use Stopwatch Class to determine execution time for an application. Using this example you can see differences in efficiency by calling Contains method of StringCollection and HashTable.


Hashtable hs = new Hashtable();
StringCollection sc = new StringCollection();
            
for (int i = 0; i < int.MaxValue/1000; i++)
{
    hs.Add(i.ToString(), i);
    sc.Add(i.ToString());
}

Random rnd = new Random();
Stopwatch timer = new Stopwatch();

int val = rnd.Next(int.MaxValue / 1000);

timer.Start();
if (sc.Contains(val.ToString()))
{
    Console.WriteLine("Contains");
}
timer.Stop();

Console.WriteLine(timer.ElapsedTicks);
timer.Reset();

timer.Start();
if (hs.Contains(val.ToString()))
{
    Console.WriteLine("Contains");
}
timer.Stop();

Console.WriteLine(timer.ElapsedTicks);

Thursday, February 17, 2011

MCTS .NET Application Development Foundation - 70-536 – Objectives List Part 7 (Implementing globalization, drawing, and text manipulation functionality in a .NET Framework application)

Format data based on culture information.
Enhance the user interface of a .NET Framework application by using brushes, pens, colors, and fonts.
Enhance the user interface of a .NET Framework application by using graphics, images, bitmaps, and icons.
Enhance the user interface of a .NET Framework application by using shapes and sizes.
Enhance the text handling capabilities of a .NET Framework application (refer System.Text namespace), and search, modify, and control text in a .NET Framework application by using regular expressions.

MCTS .NET Application Development Foundation - 70-536 – Objectives List Part 6 (Implementing interoperability, reflection, and mailing functionality in a .NET Framework application)

Expose COM components to the .NET Framework and the .NET Framework components to COM.
Call unmanaged DLL functions in a .NET Framework application, and control the marshaling of data in a .NET Framework application.
Implement reflection functionality in a .NET Framework application (refer System.Reflection namespace), and create metadata, Microsoft intermediate language (MSIL), and a PE file by using the System.Reflection.Emit namespace.
Send electronic mail to a Simple Mail Transfer Protocol (SMTP) server for delivery from a .NET Framework application.