Sunday 25 November 2012

Runtime add item to PropertyGrid Drop-down List

This sample demonstrates the technique for setting two items of a property grid from the drop-down list. These items have the type of string, but it must be simple to remake them for any other type.
Firstly, inherit the class from UITypeEditor:

public class SelEditor : System.Drawing.Design.UITypeEditor
 {       
//this is a container for strings, which can be picked-out
  ListBox Box1 = new ListBox();
  IWindowsFormsEditorService edSvc;
//this is a string array for drop-down list
  public static string[] strList;

  public SelEditor()
  {
   Box1.BorderStyle=BorderStyle.None;
//add event handler for drop-down box when item will be selected
   Box1.Click+=new EventHandler(Box1_Click);
  }

  public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle
(System.ComponentModel.ITypeDescriptorContext context)
  {
   return UITypeEditorEditStyle.DropDown;
  }

  // Displays the UI for value selection.
  public override object EditValue
(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object
value)
  {
   Box1.Items.Clear();
   Box1.Items.AddRange(strList);
   Box1.Height=Box1.PreferredHeight;
   // Uses the IWindowsFormsEditorService to display a
   // drop-down UI in the Properties window.
   edSvc = (IWindowsFormsEditorService)provider.GetService(typeof
(IWindowsFormsEditorService));
   if( edSvc != null )
   {
    edSvc.DropDownControl( Box1 );
    return Box1.SelectedItem;

   }
   return value;
  }

  private void Box1_Click(object sender, EventArgs e)
  {
   edSvc.CloseDropDown();
  }
 }


Secondly, describe a property in the class, displayed in the property grid:

 public class Class1
 {
//These are string arrays for different drop-down list.
  string[] Str1= {"AAA","BBB","CCC","DDDD"};
  string[] Str2= {"WW","EEE"};

  string s1,s2;
  public Class1()
  {
   //
   // TODO: Add constructor logic here
   //
  }


  [EditorAttribute(typeof(SelEditor), typeof(System.Drawing.Design.UITypeEditor))]
  public string STR_1
  {
   get{SelEditor.strList=Str1; return s1;}
   set{s1=value;}
  }
 
  [EditorAttribute(typeof(SelEditor), typeof(System.Drawing.Design.UITypeEditor))]
  public string STR_2
  {
   get{SelEditor.strList=Str2; return s2;}
   set{s2=value;}
  }

 }

Sunday 11 November 2012

Turn any Windows system into a full-blown Terminal Server!

XP/VS Server is a cost effective multi-user Remote Desktop access solution for Windows using the standard Microsoft Remote Desktop Protocol (RDP).

Installing XP/VS Server allows an unlimited number of users to remotely access all their Windows Desktops and Applications simultaneously.

Because compatible Remote Desktop Connection client software is already preinstalled on most devices and operating systems, seamless integration into existing networks without any hardware or software changes is assured.
XP/VS Server is suitable for small and medium enterprises and offers premium support services.

Please see the following screen-shot for details:



http://www.thinstuff.com/products/xpvs-server/

Tuesday 23 October 2012

Firebird - Context variables

-----------------------------------------
Generic user and system context variables
-----------------------------------------
for firebird 2 and above

Function:
    New built-in functions give access to some information about current
    connection and current transaction. Also they provide means to associate
    and retrieve user context data with transaction or connection.
Author:
    Nickolay Samofatov <nickolay at broadviewsoftware dot com>
Format:
    RDB$SET_CONTEXT( <namespace>, <variable>, <value> )
    RDB$GET_CONTEXT( <namespace>, <variable> )
Declared as:
  DECLARE EXTERNAL FUNCTION RDB$GET_CONTEXT
      VARCHAR(80),
      VARCHAR(80)
  RETURNS VARCHAR(255) FREE_IT;
  DECLARE EXTERNAL FUNCTION RDB$SET_CONTEXT
      VARCHAR(80),
      VARCHAR(80),
      VARCHAR(255)
  RETURNS INTEGER BY VALUE;
Usage:
  RDB$SET_CONTEXT and RDB$GET_CONTEXT set and retrieve current value for the
  context variables. Namespace name identifies a group of context variables with
  similar properties. Access rules such as the fact if variables may be read and
  written to and by whom are determined by namespace which they belong to.
  Namespace and variable names are case-sensitive.
  RDB$GET_CONTEXT retrieves current value of a variable. If variable does not
  exist in namespace return value for the function is NULL.
  RDB$SET_CONTEXT sets a value for specific variable. Function returns value of
  1 if variable existed before the call and 0 otherwise. To delete variable from
  context set its value to NULL.
  Currently, there is a fixed number of pre-defined namespaces you may use.
  USER_SESSION namespace offers access to session-specific user-defined
  variables. You can define and set value for variable with any name in this
  context. USER_TRANSACTION namespace offers the same possibilities for
  individual transactions.
  SYSTEM namespace provides read-only access to the following variables.
   Variable name        Value
  ------------------------------------------------------------------------------
   NETWORK_PROTOCOL | The network protocol used by client to connect. Currently
                    | used values: "TCPv4", "WNET", "XNET" and NULL
                    |
   CLIENT_ADDRESS   | The wire protocol address of remote client represented as
                    | string. Value is IP address in form "xxx.xxx.xxx.xxx" for
                    | TCPv4 protocol, local host name for XNET protocol and
                    | NULL for all other protocols
                    |
   DB_NAME          | Canonical name of current database. It is either alias
                    | name if connectivity via file names is not allowed or
                    | fully expanded database file name otherwise.
                    |
   ISOLATION_LEVEL  | Isolation level for current transaction. Returned values
                    | are "READ COMMITTED", "CONSISTENCY", "SNAPSHOT"
                    |
   TRANSACTION_ID   | Numeric ID for current transaction. Returned value is the
                    | same as of CURRENT_TRANSACTION pseudo-variable
                    |
   SESSION_ID       | Numeric ID for current session. Returned value is the
                    | same as of CURRENT_CONNECTION pseudo-variable
                    |
   CURRENT_USER     | Current user for the connection. Returned value is the
                    | same as of CURRENT_USER pseudo-variable
                    |
   CURRENT_ROLE     | Current role for the connection. Returned value is the
                    | same as of CURRENT_ROLE pseudo-variable
                    |
   ENGINE_VERSION   | Engine version number, e.g. "2.1.0" (since V2.1)
Notes:
   To prevent DoS attacks against Firebird Server you are not allowed to have
   more than 1000 variables stored in each transaction or session context.
Example(s):
create procedure set_context(User_ID varchar(40), Trn_ID integer) as
begin
  RDB$SET_CONTEXT('USER_TRANSACTION', 'Trn_ID', Trn_ID);
  RDB$SET_CONTEXT('USER_TRANSACTION', 'User_ID', User_ID);
end;
create table journal (
   jrn_id integer not null primary key,
   jrn_lastuser varchar(40),
   jrn_lastaddr varchar(255),
   jrn_lasttransaction integer
);
CREATE TRIGGER UI_JOURNAL FOR JOURNAL BEFORE INSERT OR UPDATE
as
begin
  new.jrn_lastuser = rdb$get_context('USER_TRANSACTION', 'User_ID');
  new.jrn_lastaddr = rdb$get_context('SYSTEM', 'CLIENT_ADDRESS');
  new.jrn_lasttransaction = rdb$get_context('USER_TRANSACTION', 'Trn_ID');
end;
execute procedure set_context('skidder', 1);
insert into journal(jrn_id) values(0);
commit;

http://www.firebirdsql.org/refdocs/langrefupd25-intfunc-set_context.html

Sunday 23 September 2012

Saturday 25 August 2012

c# - TextFieldParser

using Microsoft.VisualBasic.FileIO;

string csv = "2,1016,7/31/2008 14:22,Geoff Dalgas,6/5/2011 22:21,http://stackoverflow.com,\"Corvallis,
OR\",7679,351,81,b437f461b3fd27387c5d8ab47a293d35,34";

TextFieldParser parser = new TextFieldParser(new StringReader(csv));
// You can also read from a file
// TextFieldParser parser = new TextFieldParser("mycsvfile.csv);

parser.HasFieldsEnclosedInQuotes = true;
parser.SetDelimiters(",");
string[] fields;
while (!parser.EndOfData)
{
    fields = parser.ReadFields();
    foreach (string field in fields)
    {
        Console.WriteLine(field);
    }
}
parser.Close();

Output result:
2
1016
7/31/2008 14:22
Geoff Dalgas
6/5/2011 22:21
http://stackoverflow.com
Corvallis, OR
7679
351
81
b437f461b3fd27387c5d8ab47a293d35
34



need to add a reference to Microsoft.VisualBasic in the Add References .NET tab

.Net CSV Import/Export

The FileHelpers are a free and easy to use .NET library to import/export data from fixed length or delimited records in files, strings or streams.
http://www.filehelpers.com/

Tuesday 14 August 2012

c# Send email using Gmail smtp



using System;
using System.Windows.Forms;
using System.Net.Mail;

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

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                MailMessage mail = new MailMessage();
                SmtpClient SmtpServer = new SmtpClient("smtp.gmail.com");
                mail.From = new MailAddress("
your_email_address@gmail.com");
                mail.To.Add("to_address");
                mail.Subject = "Test Mail - 1";
                mail.Body = "mail with attachment";

                System.Net.Mail.Attachment attachment;
                attachment = new System.Net.Mail.Attachment("your attachment file");
                mail.Attachments.Add(attachment);

                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
                SmtpServer.EnableSsl = true;

                SmtpServer.Send(mail);
                MessageBox.Show("mail Send");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

Monday 13 August 2012

MailSystem.NET Component

MailSystem is a suite of .NET components that provide users with an extensive set of email tools. MailSystem provides full support for SMTP, POP3, IMAP4, NNTP, MIME, S/MIME, OpenPGP, DNS, vCard, vCalendar, Anti-Spam (Bayesian , RBL, DomainKeys), Queueing, Mail Merge and WhoIs

http://mailsystem.codeplex.com/

Wednesday 25 July 2012

C# Process.Start

Starts a process resource and associates it with a Process component.
Example: call external application to view documents and web pages. It also executes EXE programs and external command line utilities.

Program that opens directory [C#]
using System.Diagnostics;
class Program
{
    static void Main()
    {
     //
     // Use Process.Start here.
     //
      Process.Start("C:\\");
    }
}

Program that opens text file [C#]
using System.Diagnostics;
class Program
{
    static void Main()
    {
     //
     // Open the file "example.txt" that is in the same directory as
     // your .exe file you are running.
     //
      Process.Start("example.txt");
    }
}

Program that searches Google [C#]
using System.Diagnostics;
class Program
{
    static void Main()
    {
      // Search Google.
       Process.Start("http://google.com/");
    }
}

Program that starts WINWORD.EXE [C#]
using System.Diagnostics;
class Program
{
    static void Main()
    {
     // A.
     // Open specified Word file.
     OpenMicrosoftWord(@"C:\Users\Sam\Documents\Gears.docx");
    }
    /// <summary>
    /// Open specified word document.
    /// </summary>
    static void OpenMicrosoftWord(string f)
    {
      ProcessStartInfo startInfo = new ProcessStartInfo();
      startInfo.FileName = "WINWORD.EXE";
      startInfo.Arguments = f;
      Process.Start(startInfo);
    }
}

Program that runs EXE [C#]
using System.Diagnostics;
class Program
{
    static void Main()
    {
      LaunchCommandLineApp();
    }
    /// <summary>
    /// Launch the  application with some options set.
    /// </summary>
    static void LaunchCommandLineApp()
    {
      // For the example
      const string ex1 = "C:\\";
      const string ex2 = "C:\\Dir";

      // Use ProcessStartInfo class
      ProcessStartInfo startInfo = new ProcessStartInfo();
      startInfo.CreateNoWindow = false;
      startInfo.UseShellExecute = false;
      startInfo.FileName = "myprog.exe";
      startInfo.WindowStyle = ProcessWindowStyle.Hidden;
      startInfo.Arguments = "-f d " + ex2;

 try
 {
     // Start the process with the info we specified.
     // Call WaitForExit and then the using statement will close.
     using (Process exeProcess = Process.Start(startInfo))
     {
       exeProcess.WaitForExit();
     }
 }
 catch
 {
     // Log error.
 }
    }
}

Tuesday 19 June 2012

InnoSetup Dependency Installer

http://www.codeproject.com/Articles/20868/NET-Framework-1-1-2-0-3-5-Installer-for-InnoSetup

InnoSetup function to check .Net version


function IsDotNetDetected(version: string; service: cardinal): boolean;
// Indicates whether the specified version and service pack of the .NET Framework is installed.
//
// version -- Specify one of these strings for the required .NET Framework version:
//    'v1.1.4322'     .NET Framework 1.1
//    'v2.0.50727'    .NET Framework 2.0
//    'v3.0'          .NET Framework 3.0
//    'v3.5'          .NET Framework 3.5
//    'v4\Client'     .NET Framework 4.0 Client Profile
//    'v4\Full'       .NET Framework 4.0 Full Installation
//
// service -- Specify any non-negative integer for the required service pack level:
//    0               No service packs required
//    1, 2, etc.      Service pack 1, 2, etc. required
var
    key: string;
    install, serviceCount: cardinal;
    success: boolean;
begin
    key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + version;
    // .NET 3.0 uses value InstallSuccess in subkey Setup
    if Pos('v3.0', version) = 1 then begin
        success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install);
    end else begin
        success := RegQueryDWordValue(HKLM, key, 'Install', install);
    end;
    // .NET 4.0 uses value Servicing instead of SP
    if Pos('v4', version) = 1 then begin
        success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount);
    end else begin
        success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount);
    end;
    result := success and (install = 1) and (serviceCount >= service);
end;

function InitializeSetup(): Boolean;
begin
    if not IsDotNetDetected('v4\Client', 0) then begin
        MsgBox('MyApp requires Microsoft .NET Framework 4.0 Client Profile.'#13#13
            'Please use Windows Update to install this version,'#13
            'and then re-run the MyApp setup program.', mbInformation, MB_OK);
        result := false;
    end else
        result := true;
end;

Friday 11 May 2012

Saturday 5 May 2012

.Net File.Exists, Directory.Exists

// C# Example code for File.Exists, Directory.Exists
using System;
using System.IO;
using System.Collections;

public class RecursiveFileProcessor 
{
    public static void Main(string[] args) 
    {
        foreach(string path in args) 
        {
            if(File.Exists(path)) 
            {
                // This path is a file
                ProcessFile(path); 
            }               
            else if(Directory.Exists(path)) 
            {
                // This path is a directory
                ProcessDirectory(path);
            }
            else 
            {
                Console.WriteLine("{0} is not a valid file or directory.", path);
            }        
        }        
    }


    // Process all files in the directory passed in, recurse on any directories 
    // that are found, and process the files they contain.
    public static void ProcessDirectory(string targetDirectory) 
    {
        // Process the list of files found in the directory.
        string [] fileEntries = Directory.GetFiles(targetDirectory);
        foreach(string fileName in fileEntries)
            ProcessFile(fileName);

        // Recurse into subdirectories of this directory.
        string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
        foreach(string subdirectory in subdirectoryEntries)
            ProcessDirectory(subdirectory);
    }

    // Insert logic for processing found files here.
    public static void ProcessFile(string path) 
    {
        Console.WriteLine("Processed file '{0}'.", path);     
    }
}

Friday 4 May 2012

Windows System Folders

// Sample for the Environment.GetFolderPath method
using System;

class Sample
{
    public static void Main()
    {
    Console.WriteLine();
    Console.WriteLine("GetFolderPath: {0}",
                 Environment.GetFolderPath(Environment.SpecialFolder.System));
    }
}
/*
This example produces the following results:

GetFolderPath: C:\WINNT\System32
*/


Environment.SpecialFolder Enumeration
http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Friday 27 April 2012

Reading and Writing XML Files

To create or manipulate XML files, you must use the classes and methods inside the System.XML namespace of the .NET Framework.

Writing XML FilesWe can use the XmlWriter class to write XML files. It allows you to write XML text into a stream and then save it into an xml file.

using System.Xml;

public class Program
{
    public static void Main()
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        XmlWriter writer = XmlWriter.Create("Products.xml", settings);
        writer.WriteStartDocument();
        writer.WriteComment("This file is generated by the program.");
        writer.WriteStartElement("Product");
        writer.WriteAttributeString("ID", "001");
        writer.WriteAttributeString("Name", "Soap");
        writer.WriteElementString("Price", "10.00");
        writer.WriteStartElement("OtherDetails");
        writer.WriteElementString("BrandName", "X Soap");
        writer.WriteElementString("Manufacturer", "X Company");
        writer.WriteEndElement();
        writer.WriteEndDocument();

        writer.Flush();
        writer.Close();
    }
}


We first import the System.Xml namespace. We use the XmlWriterSettings class to create a setting for the XmlWriter that we will use. We dictated the program to use proper indention when writing the xml by using this settings. We then create an XmlWriter object by calling the XmlWriter.Create method and supplying the filename and the XmlWriterSettings object.

Using the XmlWriter class, we can write our xml. We first use the XmlWriter.WriteStartDocument() method which writes the xml declaration you find on the top of most xml files. Next we create a sample comment using teh XmlWriter.WriteComment() method. To write an Xml Element, we use the XmlWriter.WriteStartElement() and supply the name of the element as the argument. The XmlWriter.WriteStartElement() must be paired with XmlWriter.WriteEndElement which writes the closing tag of that element. We now create some attributes for the element using the XmlWriter.WriteAttributeString() method and supply the name and the value for that attribute.

We used the XmlWriter.WriteElementString() method with a name and a value as the arguments to write an element that is wrapping a value. We then nested another element inside the Products element by writing one more set of XmlWriter.WriteStartElement() and XmlWriter.WriteEndElement() . Inside it, we add two more elements that contain values. To mark the end of the document, we simly call the XmlWriter.WriteEndDocument() method.
Finally, we used the XmlWriter.Flush() method to clean the contents of the stream and the XmlWriter.Close() method to save the file and stop the program from using it.
The above code will produce the following XML file contents:

<?xml version="1.0" encoding="utf-8"?>
<!--This file is generated by the program.-->
<Product ID="001" Name="Soap">
  <Price>10.00</Price>
  <OtherDetails>
    <BrandName>X Soap</BrandName>
    <Manufacturer>X Company</Manufacturer>
  </OtherDetails>
</Product>


Reading XML Files
To read xml files, we can use the XmlReader class. We will use the XML file we created earlier to assign the values into variables. Note that we will simply use variables for storing the values from the XML. A better approach is by creating a Products class the follows the heirarchy of the XML file. The following program demonstrates the use of XmlReader class.

using System;
using System.Xml;

public class Program
{
    public static void Main()
    {
        XmlReader reader = XmlReader.Create("Products.xml");

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element
                && reader.Name == "Product")
            {
                Console.WriteLine("ID = " + reader.GetAttribute(0));
                Console.WriteLine("Name = " + reader.GetAttribute(1));

                while (reader.NodeType != XmlNodeType.EndElement)
                {
                    reader.Read();
                    if (reader.Name == "Price")
                    {
                        while (reader.NodeType != XmlNodeType.EndElement)
                        {
                            reader.Read();
                            if (reader.NodeType == XmlNodeType.Text)
                            {
                                Console.WriteLine("Price = {0:C}", Double.Parse(reader.Value));
                            }
                        }

                        reader.Read();
                    } //end if
                    if (reader.Name == "OtherDetails")
                    {
                        while (reader.NodeType != XmlNodeType.EndElement)
                        {
                            reader.Read();
                            if (reader.Name == "BrandName")
                            {
                                while (reader.NodeType != XmlNodeType.EndElement)
                                {
                                    reader.Read();
                                    if (reader.NodeType == XmlNodeType.Text)
                                    {
                                        Console.WriteLine("Brand Name = " + reader.Value);
                                    }
                                }
                                reader.Read();
                            } //end if

                            if (reader.Name == "Manufacturer")
                            {
                                while (reader.NodeType != XmlNodeType.EndElement)
                                {
                                    reader.Read();
                                    if (reader.NodeType == XmlNodeType.Text)
                                    {
                                        Console.WriteLine("Manufacturer = " + reader.Value);
                                    }
                                }

                            } //end if
                        }
                    } //end if
                } //end while
            } //end if

        } //end while
    }
}


Output:
ID = 001
Name = Soap
Price = $10.00
Brand Name = X Soap
Manufacturer = X Company


There are other ways to read Xml files but this tutorial will focus on using the XmlReader class. First, we create an XmlReader object using the static method Create and passing the filename of the XML file that will be read.

XmlReader reader = XmlReader.Create("Products.xml");

We now enter a loop that will read each node in the xml file including the whitespaces. We use the XmlReader.Read() that returns true if there are more nodes to read or false if there is no more or if it reaches the end of the file.
We first look at the Product element. The first condition checks if the current node read by the reader is an element and has a name of "Product". The XmlNodeTpe enumeration list all the possible node types including whitespaces, text and comments. We then show the values of the attributes of the product element:

Console.WriteLine("ID = " + reader.GetAttribute(0));
Console.WriteLine("Name = " + reader.GetAttribute(1));

The GetAttribute() method gets the values of the attribute of an element. The number indicates what attribute you are getting. 0 indicates the first attribute and 1 indicates the second attribute.
You will now encounter a series of nested while and if statements. The first while loop will search for the Price element. The Read() method will go to the next node while it is not an end element. If the type of the node is a text, we display it on the screen.
Basically, reading xml files using XmlReader requires you to look carefully at the structure of your XML.

Thursday 26 April 2012

Select XML Nodes by Attribute Value

Select XML Nodes by Attribute Value [C#]


This example shows how to select nodes from XML document by attribute value. Use method XmlNode.Selec­tNodes to get list of nodes selected by the XPath expression. Suppose we have this XML file.
[XML]
<Names>
    <Name type="M">John</Name>
    <Name type="F">Susan</Name>
    <Name type="M">David</Name>
</Names>

To get all name nodes use XPath expression /Names/Name. To get only male names (to select all nodes with specific XML attribute) use XPath expression /Names/Name[@type='M'].

[C#]
XmlDocument xml = new XmlDocument();
xml.LoadXml(str);  // suppose that str string contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/Names/Name[@type='M']");
foreach (XmlNode xn in xnList)
{
  Console.WriteLine(xn.InnerText);
}

The output is:
John
David

Saturday 21 April 2012

Adding a simple text watermark to an image

if (pictureBox1.Image != null)
{
    //Create image.
    Image tmp = pictureBox1.Image;
    //Create graphics object for alteration.
    Graphics g = Graphics.FromImage(tmp);

    //Create string to draw.
    String wmString = "Code Project";
    //Create font and brush.
    Font wmFont = new Font("Trebuchet MS", 10);
    SolidBrush wmBrush = new SolidBrush(Color.Black);
    //Create point for upper-left corner of drawing.
    PointF wmPoint = new PointF(10.0F, 10.0F);
    //Draw string to image.
    g.DrawString(wmString, wmFont, wmBrush, wmPoint);
    //Load the new image to picturebox
    pictureBox1.Image= tmp;       
    //Release graphics object.
    g.Dispose();               
}

Friday 20 April 2012

.Net Windows Form Event Sequence

The events in the lifecycle of a Form from the time it is launched to the time it is closed are listed below:

  • Move: This event occurs when the form is moved. Although by default, when a form is instantiated and launched, the user does not move it, yet this event is triggered before the Load event occurs.
  • Load: This event occurs before a form is displayed for the first time.
  • VisibleChanged: This event occurs when the Visible property value changes.
  • Activated: This event occurs when the form is activated in code or by the user.
  • Shown: This event occurs whenever the form is first displayed. 
  • Paint: This event occurs when the control is redrawn.
  • Deactivate: This event occurs when the form loses focus and is not the active form.
  • Closing: This event occurs when the form is closing.
  • Closed: This event occurs when the form is being closed.

Friday 6 April 2012

Validating Properties In A .Net Propertygrid Control


The easiest way to validate a certain property in a .Net propertygrid control is using the PropertyValueChanged event.The code bellow shows how to limit the valid range of Age property to be 1-150

using System.Windows.Forms;
namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //init person object
            Person person = new Person();
            person.FirstName = "George";
            person.Age = 33;
            propertyGrid.SelectedObject = person;
            propertyGrid.PropertyValueChanged+=  new PropertyValueChangedEventHandler( propertyGrid_PropertyValueChanged );
        }


        private void propertyGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            if (e.ChangedItem.Label == "Age" && !IsAgeValid((int)e.ChangedItem.Value) )
            {
                // the entered age value is wrong - show error message
                e.ChangedItem.PropertyDescriptor.SetValue( propertyGrid.SelectedObject, e.OldValue);
                MessageBox.Show("Wrong age", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }


        ///<summary>
        /// Determines whether age is valid
        /// </summary>
        /// <param name="age">The age.</param>
        /// <returns>
        /// <c>true</c> if is age valid ; otherwise, <c>false</c>.
        /// </returns>

        private static bool IsAgeValid( int age )
        {
            return ((age > 0) && (age < 150));
        }
    }
}

Saturday 24 March 2012

Adding Start menu to Windows 8 Consumer Preview

Windows 8 Metro interface is good for tablet. But for desktop users, not much productivity gain.
You can add the good old Start menu to Windows 8 using this tool http://www.stardock.com/products/start8/

Saturday 3 March 2012

Opportunistic Locking & SMB2

What is Opportunistic Locking?

Opportunistic locking (oplocks) is a Windows-specific mechanism for client/server databases to allow multiple processes to lock the same file while allowing for local (client) data caching to improve performance over Windows networks. Unfortunately, the default setting of the oplocks mechanism that enhances the performance of one type of database (client/server) also introduces data integrity issues for other database types (file system/ISAM). Microsoft's documentation states "An opportunistic lock (also called an oplock) is a lock placed by a client on a file residing on a server. In most cases, a client requests an oplock so it can cache data locally, thus reducing network traffic and improving apparent response time. Oplocks are used by network redirectors on clients with remote servers, as well as by client applications on local servers" and "Oplocks are requests from the client to the server. From the point of view of the client, they are opportunistic. In other words, the server grants such locks whenever other factors make the locks possible.".

Related: Opportunistic Locks, Microsoft Developer Network (MSDN)


What Is SMB2?
SMB2 is the second generation of server message block (SMB) communication on Windows networks. SMB2 was introduced in Windows Vista and Windows Server 2008 to enable faster communication between computers that are running Windows Vista and Windows Server 2008. Previous Windows versions used SMB1, also called "traditional" SMB. SMB1 is still supported in current Windows versions (Vista, Server 2008, 7) for backward compatibility.



Disabling Oplocks on Windows Client PCs
To disable oplocks on a Windows client PC (a Windows PC that accesses an embedded database table hosted on another PC), change or add the following Registry values:
  • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\MRXSmb\Parameters OplocksDisabled = 1

Disabling Oplocks on Windows Servers
To disable oplocks on a Windows server (a Windows PC that hosts an embedded database table accessed from another PC), change or add the following Registry values:
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters EnableOplocks = 0

Disabling Oplocks on SMB2
To disable SMB2 on a Windows Server 2008 or Windows Vista/7/8 PC hosting embedded database tables, change or add the following Registry value:
  • HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters SMB2 = 0
Once SMB2 is disabled, SMB1 will be used again and the methods described above applied to disable oplocks for SMB1.

Saturday 4 February 2012

Some useful web design tools


1) Buttons - http://code.google.com/p/sexybuttons/

2) Css Print Framework - http://code.google.com/p/hartija/

3) Show large photo using jquery -  http://code.google.com/p/jquery-largephotobox/

4) slideshow using jquery -  http://code.google.com/p/a-slideshow/

Change the precision of all decimal columns in every table in the database

Found a script on the net to change decimal column precision for MSSQL database. Can be modified to change other data type.

Change the precision of all decimal columns in every table in the database
Get the columns from information_schema based on type and scale, then alter them to have the desired scale.
declare @col sysname
declare @tbl sysname
declare @sql nvarchar(256)
declare crsFix cursor for
select table_name, Column_name from information_schema.columns
where data_type = 'decimal' and Numeric_Scale = 3
open crsFix
fetch next from crsFix into @tbl, @col
while(@@Fetch_Status = 0)
Begin
    set @sql = 'Alter table [' + @tbl + '] alter column [' + @col + '] decimal(38,2) ' 
    print @sql
    exec sp_executesql @sql
    fetch next from crsFix into @tbl, @col
End
close crsFix
deallocate crsFix

Malaysian Passport Renewal

Gone to renew my passport the other day. Processing was fast albeit some queueing and waiting.

Steps and requirements:
1) download and print the application form. Use laser printer. Fill in the form details
2) 2 copies of passport size photo(3.5 x 5 cm).
3) MyKad identification card.
4) RM300.00 for 32 pages 5 years passport.

Go to immigration office. Get a queue number. Wait for your turn. Submit your application form. After checking your application form and MyKad, they will request you to come back in 2 hours to get your new passport.

Monday 23 January 2012

How the PCB for bonus is calculated

The Potongan Cukai Bulanan (PCB, a.k.a. Scheduled Monthly Tax Deduction) calculation for bonus is not so straight forward.

Here is how it will be calculated.

Assuming you are not married, your monthly salary is RM4,000, you are contributing 11% from your salary to your EPF savings, and you received 2 months bonus in January 2010.

Salary = RM4,000
EPF deduction = RM440 (maximum total EPF deduction allowed for PCB calculation is only RM500, therefore available balance left is RM500 - RM440 = RM60)
Salary to calculate PCB
= Gross salary - EPF deduction
= RM4,000 - RM440
= RM3,560

PCB 2010 according to table for RM3,560 = RM87

2 months bonus = RM8,000
EPF deduction = RM880
Maximum available EPF deduction for PCB calculation = RM500 - RM440 = RM60
Therefore, the EPF deduction should be RM60 instead of RM880

Bonus to calculate PCB
= Gross bonus - EPF deduction left
= RM8,000 - RM60
= RM7,940

The amount for bonus PCB calculation has a formula like this:
(1/12 x net_bonus) + net_salary

Therefore, amount
= (1/12 x RM7,940) + RM3,560
= RM4,221.67

PCB 2010 according to table for RM4,221.67 = RM194

PCB for bonus = (RM194 - RM87) x 12 = RM1,284

Total PCB for the month
= PCB for salary + PCB for bonus
= RM87 + RM1,284
= RM1,371

Therefore, for the month with bonus:
Gross salary+bonus = RM12,000
EPF contribution from employee @ 11% = RM1,320
EPF contribution from employer @ 12% = RM1,440
SOCSO contribution from employee = RM14.75
SOCSO contribution from employer = RM51.65
PCB deduction = RM1,371
Amount you'll get = RM12,000 - RM1,371 - RM14.75 - RM1,320 = RM9,294.25