Tuesday, December 16, 2008

My Visual Studio Error Puzzle

OK, here’s my small puzzle I came across today.

Start Visual Studio 2008. Select New Project -> Visual C# -> Windows -> Windows Forms Application. WindowsFormsApplication1 seems to be a good enough name. Hit OK.

Now, go to Solution Explorer, right-click WindowsFormsApplication1 and select ‘add Class’. Class1 seems to be a good enough name. Hit OK.

Now, make this class inherit from SoapHttpClientProtocol. For this purpose, add a reference to ‘System.Web.Services’ to References.

Now, decorate this new Class1 with the WebServiceBindingAttribute.
You’ll end up with code as simple as this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.Web.Services;

namespace WindowsFormsApplication1
{
[WebServiceBindingAttribute(Name = "AsyncRequestSoap",
Namespace = "http://tempuri.org/")]
class Class1 : SoapHttpClientProtocol
{
}
}

The project builds without errors and, if actual code is added to Class1, it will execute without errors. However, if I double-click 'Class1.cs' in Solution Explorer, I would be presented with an error screen like this one:



This seems to be a bug in Visual Studio since it’s obvious that WebServiceBindingAttribute attribute is added to the class and the application will compile and execute regardless of the error screen. Seems to be safe to ignore. However, I did not find clarification on that yet. by . Also posted on my website

Wednesday, December 10, 2008

I'm a scanning developer

I spent a couple of days investigating what this device can do:

3M Full Page Scanner

This smart device is supposed to be able to scan all sorts of passports and other identification documents and retrieve values like names, date of birth, document expiry dates and such. The documentation is not very straightforward and the code samples are in C++ only so it took me a bit of time to figure out how to operate this device programmatically.

First of all, a DocAuth.dll has to be referenced. (There is a bunch of development resources on the CD that comes with the device, and the dll’s are there too). After that, an object of a ReaderClass can be created.

using DOCAUTHLib;
...
r = new ReaderClass();

then the connection to the device has to be established

r.Connect("D72086", "Scanner", "ProcessingDone");

"ProcessingDone" is the comma-separated string that specifies which events will be captured. Other events are “NewDocument ”, “DocumentIdentified ”, etc. After the connection is established, you can subscribe to the scanner events.

r._IReaderEvents_Event_ReaderEvent += new _IReaderEvents_ReaderEventEventHandler(r__IReaderEvents_Event_ReaderEvent);
void r__IReaderEvents_Event_ReaderEvent(string @event){}

In this case, for example, if subscription is made to “ProcessingDone” event only, then whenever a new document is placed into the scanner, it will be automatically scaneed and after that the event will be fired and captured by the function. This might not always be very handy, so I chose to run scans manually. This is done by simply calling

r.DoScan();

To use the device as a simple image scanner, you can instruct it to process the image as a generic image.

r.ForceDocumentProcessing("Generic Image Capture", "");

The image, for some reason, is returned as a string.

string s = r.RetrieveImageItem("Visible", “BMP”); // or JPG, etc.

Alternatively, the image can be saved to disk straight away.

r.RetrieveImageItemAndSave("Visible", “JPG”, @"C:\scan.jpg");

Now, when you want to use this device for automatic retrieval of data from various documents, things become more interesting. Apparently, the list of documents that can be recognised, is stored on the device somewhere. Here is how this can be accessed:

r.RetrieveDatabaseList("");
string dv = string.Empty;
for (int i = 0; i < r.DatabaseListCount; i++)
{
dv = r.get_DatabaseListValue(i);
}

The “database list” is the list of types of documents that are available for recognition. It contains values like “2Line44” or “3Line30”. After the type has been selected, you can access the list of more particular documents belonging to this type in a similar way:

r.RetrieveDocumentItemList(“2Line44”);
string lv = string.Empty;
for (int i = 0; i < r.DocumentItemListCount; i++)
{
lv = r.get_DocumentItemListValue(i);
}

The ‘document item list’ contains values like “Hungarian_Passport”, “Netherlands_Old_Passport” etc. – a lot of them.

Now, after a particular document that we are going to try to read is chosen, we can go and access all the information that the scanner is trying to extract from it.

r.Connect("D72086", "Scanner", "ProcessingDone");
r.ForceDocumentProcessing("2Line44", "Australia_Passport");
r.DoScan();
string fName = r.RetrieveTextItem("@mrz_surname");
string lName = r.RetrieveTextItem("@mrz_givname");

If we’re lucky, the strings will contain proper name of the passport owner.

Now I can go and write a small application that can be used, for example, to add clients to a company database. It will scan the client’s passport and automatically populate fields like name, sex, DOB and a few others.

Overall, it's a fun device to work with. :-)

by . Also posted on my website

I'm a stylish developer

Only today I realized that it's easy to add my own stylesheet to the blog's template so I don't have to format each post which contains code by adding styles to it.

Oh well, I guess you should refer to the blog title, that explains it. Just in case you're a bit like me, though:

  • Simply copy the CSS you want to use to the clipboard
  • In Blogger, go to Template: Edit HTML. In the large textbox in the middle of the page, scroll down to the beginning of the CSS area (it starts with body { ). Just before that line, paste in the CSS you copied
  • Click Save Template
  • (courtesty of How do style my recipe on my blog?)

    by . Also posted on my website

    Thursday, November 13, 2008

    Small Thing Learned Today

    Let's say I have some data regarding the buildings and people who built them - one building obviously can have multiple builders.

    BuildingID  BuilderName
    ----------- ----------------
    1 Paul
    2 John
    3 Bob
    1 George
    2 Sam
    3 Fred
    1 Joe
    2 Phil

    What I need here, is a report in the following format:

    BuildingID  builder_list
    ----------- --------------------------
    1 George, Joe, Paul
    2 John, Phil, Sam
    3 Bob, Fred

    I found a very good guide on the problem:

    Concatenating row values in Transact-SQL

    This is the solution I chose from the suggested ones:

    WITH CTE (BuildingID, builder_list, builder_name, length)
    AS(SELECT BuildingID, CAST( '' AS VARCHAR(8000) ), CAST( '' AS VARCHAR(8000) ), 0
    FROM tblBuildings
    GROUP BY BuildingID
    UNION ALL
    SELECT p.BuildingID, CAST(builder_list +
    CASE WHEN length = 0 THEN '' ELSE ', ' END + BuilderName AS VARCHAR(8000) ),
    CAST(BuilderName AS VARCHAR(8000)), length + 1
    FROM CTE c
    INNER JOIN tblBuilders p
    ON c.BuildingID = p.BuildingID
    WHERE p.BuilderName > c.builder_name)

    SELECT BuildingID, builder_list
    FROM (SELECT BuildingID, builder_list,
    RANK() OVER (PARTITION BY BuildingID ORDER BY length DESC)
    FROM CTE) D (BuildingID, builder_list, rank)
    WHERE rank = 1;

    It looks a bit complex to understand, but does exactly what I need!

    by . Also posted on my website

    Wednesday, November 5, 2008

    Small Thing Learned Today

    You can actually assign default values to stored procedure parameters. I suspect I knew that sometime, but totally forgotter. All I need to do is declare them like this

    CREATE PROCEDURE [dbo].[prSP_MyStoredProcWithDefaultParameters]
    (@someID int,@someParam1 int = -1,@someParam2 int = -1,@someParam3 int = -1,
    @someParam4 int = -1,//...@someParam999 int = -1)

    Now if I have less than 999 'someParameters', I can still call the stored procedure. I don't really care how many parameters are in the list, as long as there is no more than 999 of them.

    List myParams = new List();
    List paramList = new List();
    // add some values to the list
    foreach (int myInt in paramList)
    {
    if (paramList.IndexOf(myInt) > 998)
    {
    break;
    }
    else
    {
    myParams.Add(DbManager.CreateInParameter("someParam" +
    (paramList.IndexOf(myInt) + 1).ToString(), DbType.Int32, myInt));
    }
    }

    Well, I guess I have to take care to assign the really important parameters of course.

    I can have default values in SQL Server functions too, but, unfortunately I have to specify the keyword 'default' while calling them.

    So, if a function is defined as

    CREATE FUNCTION [dbo].[fn_MyFunctionWithDefaultParameters](@someID int,
    @someParam1 int = -1,@someParam2 int = -1,
    @someParam3 int = -1,@someParam4 int = -1,
    //...
    @someParam999 int = -1)

    I need to call it this way:

    dbo.fn_MyFunctionWithDefaultParameters(1, 2, 3, default, default, 
    /* snip a few hundred more*/
    default)

    Still quite useful, but I wish I could call it just like this

    dbo.fn_MyFunctionWithDefaultParameters(1, 2, 3)

    or this

    dbo.fn_MyFunctionWithDefaultParameters(1, 2, 3, default, 5, 6)
    by . Also posted on my website

    Tuesday, October 28, 2008

    Offer Accepted

    Finally got an offer from that company I mentioned before - the one that everyone knows about. And accepted, too. Looking forward to it. The company is huge, though it is not a software development or a consulting company. The development team is about 30 people and only develops software for company's internal needs. I start in 4 weeks.

    Oh well, enough about it for now I guess.

    by . Also posted on my website

    Thursday, October 23, 2008

    A Quick One Before I Forget

    Cause it's Friday.

    I came across a very good list of tips and tricks that every developer who uses Visual Studio 2008 should know:

    Essential Visual Studio Tips & Tricks that Every Developer Should Know.

    Ones I did not know are: 1, 4, 7, 10.

    by . Also posted on my website

    Small Thing Learned Today

    I needed to hide some of the rows of a databound DataGridView at runtime. However, when I added a piece of code to do that,

    foreach (DataGridViewRow row in myDataGridView.Rows)
    {
    if (someCondition)
    {
    row.Visible = false;
    }
    }

    I was getting an exception sometimes:

    'Row associated with the currency manager's position cannot be made invisible.'

    I found out that the exception was happening when the row I was trying to set invisible was selected. The solution to this little problem is to change the code the following way:

    CurrencyManager currencyManager1 = (CurrencyManager)
    BindingContext[myDataGridView.DataSource];
    currencyManager1.SuspendBinding();
    foreach (DataGridViewRow row in myDataGridView.Rows)
    {
    if (someCondition)
    {
    row.Visible = false;
    }
    }
    myBindingSource.ResumeBinding(); // this is myDataGridView's binding source
    by . Also posted on my website

    Monday, October 20, 2008

    Small Thing Learned Today

    So I needed to show a type name in the textbox today. Like 'DateTime', or 'Integer' etc. I decided to create a binding source and bind to System.Type.Name like this:

    this.propertyTypeBindingSource.DataSource = typeof(System.Type);
    /* snip */
    this.nameTextBox.DataBindings.Add(new System.Windows.Forms.Binding
    ("Text", this.propertyTypeBindingSource, "Name", true));
    /* snip */
    Type PropertyType = typeof(DateTime);
    this.propertyTypeBindingSource.DataSource = PropertyType;

    However, when I try to run the application, I get an exception

    "Cannot bind to the property or column Name on the DataSource. Parameter name: dataMember"

    So, looks like I'm not allowed to bind directly to System.Type. Maybe I have to do some simple trick ... I create a class

    public class StubPropertyType
    {
    public StubPropertyType(Type type)
    {
    this.StubPropertyTypeName = type.Name;
    }
    private string _stubPropertyTypeName = string.Empty;
    public string StubPropertyTypeName
    {
    get { return _stubPropertyTypeName; }
    set { _stubPropertyTypeName = value; }
    }
    }

    and my binding now looks along these lines:

    this.propertyStubBindingSource.DataSource = typeof(StubPropertyType);
    /* snip */
    this.nameTextBox.DataBindings.Add(new System.Windows.Forms.Binding
    ("Text", this.propertyStubBindingSource, "StubPropertyTypeName", true));
    /* snip */
    Type PropertyType = typeof(DateTime);
    StubPropertyType stub = new StubPropertyType(PropertyType);
    this.propertyStubBindingSource.DataSource = stub;

    And it works like a charm!

    by . Also posted on my website

    Wednesday, October 15, 2008

    Small Thing Learned Today

    In SQL Server 2005, if I need to know what are the columns and data types of the certain table, I can run a simple query to know it:

    select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='MyTable'

    What's especially good for me is that it not only works with tables, but with views too. My current task is to create an interface for users which would allow them to generate custom reports through a set of views. They need to be able to apply criteria to the reports so that if the column's data type is datetime, they can use 'Is Before' or 'Is After', but on integer columns they can use 'Larger Than' etc.

    by . Also posted on my website

    Tuesday, October 14, 2008

    Very Busy This Week

    On Friday I will have to go for an 'online test'. That's it, no more details. I've been for a 'first round' interview, and after about a week or so I got a call and was invited to this testing. I have no idea what the testing will be about, but I studied everything relevant on Tech Interviews and even registered with Brainbench cause they have a free C# test there. It's a bit hard to prepare when you don't know what you're preparing for. Well it's a C# development position, so this gives me sort of an idea.

    by . Also posted on my website

    Thursday, October 9, 2008

    Stack Overflow!

    This site

    seems to be very useful for those seeking answers for their computer-related questions. I fould a link to it here.

    This is how it works:


    Every question in Stack Overflow is like the Wikipedia article for some extremely narrow, specific programming question. How do I enlarge a fizzbar without overwriting the user’s snibbit? This question should only appear once in the site. Duplicates should be cleaned up quickly and redirected to the original question.

    Some people propose answers. Others vote on those answers. If you see the right answer, vote it up. If an answer is obviously wrong (or inferior in some way), you vote it down. Very quickly, the best answers bubble to the top. The person who asked the question in the first place also has the ability to designate one answer as the “accepted” answer, but this isn’t required. The accepted answer floats above all the other answers.

    Read more.

    by . Also posted on my website

    Tuesday, October 7, 2008

    Browsing The Job Listings

    Is there even such thing as a 'Junior Project Manager'? The title caught my eye as I never seen anything like this before. And the salary on offer is even significantly less than I have as a developer at the moment ...

    by . Also posted on my website

    Monday, October 6, 2008

    Snippets

    You know how in Visual Studio you can type 'mbox', press Tab twice and Visual Studio will convert it into

    MessageBox.Show("Test");

    Or, you can type 'ctor', press Tab twice and the constructor for the class will be generated?

    This can be customised. Have a look at the following file:

    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
    <Header>
    <Title>props</Title>
    <Shortcut>props</Shortcut>
    <Description>Code snippet that checks for a null property</Description>
    <SnippetTypes>
    <SnippetType>Expansion</SnippetType>
    </SnippetTypes>
    </Header>
    <Snippet>
    <Declarations>
    <Literal>
    <ID>field</ID>
    <ToolTip>backing store</ToolTip>
    <Default>mProp</Default>
    </Literal>
    <Literal>
    <ID>type</ID>
    <ToolTip>Property type</ToolTip>
    <Default>int</Default>
    </Literal>
    <Literal>
    <ID>property</ID>
    <ToolTip>Property name</ToolTip>
    <Default>MyProperty</Default>
    </Literal>
    </Declarations>
    <Code Language="csharp">
    <![CDATA[private $type$ $field$;
    public $type$ $property$
    {
    get
    {
    if (this.$field$ == null)
    {
    this.$field$ = new $type$();
    }
    return this.$field$;
    }
    set {this.$field$ = value;}
    }
    $end$]]>
    </Code>
    </Snippet>
    </CodeSnippet>
    </CodeSnippets>

    You can now save it with any name you like, and then press Ctrl-K, B (or choose Tools -> Code snippets manager), press 'Import', navigate to this file and select it.

    Now, if you type 'props' and press Tab twice, the system will convert it into the following little pattern for getting a private member through a property, with checking if it is null:

    private int mProp;
    public int MyProperty
    {
    get
    {
    if (this.mProp == null)
    {
    this.mProp = new int();
    }
    return this.mProp;
    }
    set {this.mProp = value;}
    }

    From here it's easy to understand how to make 'snippets' that do anything you want.

    by . Also posted on my website

    Sunday, October 5, 2008

    Interview Question Of The Day

    The easiest of those I did not answer today was 'What is the difference between a class and a struct?'.

    Yes, everyone should know it. For explanation why I did not, refer to the title of this blog. Later I found quite a detailed answer here:

    Difference between class and struct in C#

    I knew some of these, but did not realize there are that many. Some can be combined though, for example "When you instantiate a class, it will be allocated on the heap.When you instantiate a struct, it gets created on the stack" is obvious if you already know that "Classes are reference types and structs are value types".

    by . Also posted on my website

    A Well-known Interview Tip

    Everyone knows this one. You should research the company you're going to for an interview - what it does, what are their goals, who their main competitors are etc.

    Sometimes, however, you have a luxury of skipping this step. If a company is so huge or well-known that literally EVERYONE knows it, I think it's pretty safe to skip it.

    I was at such company last week, maybe for the first time in my life. No, they didn't ask me 'so, what do you know about us?' :)

    by . Also posted on my website

    Thursday, October 2, 2008

    Exciting Day At Work

    Implementing permissions in the application.The database structure is there. There is "Permissions" table, there is "Roles" table, there is "RolesPermissions" table. There is an interface that allows to create additional roles and add different permissions to them. So, what is the exciting thing that's not yet implemented?

    I have to go through the code and insert pieces of code that actually check user's permissions and look like this:

    if (CurrentUser.IsAllowed(Permissions.MyPermissionToSeeSomeHighlySensitiveData))
    {
    //existing code remains here
    }
    else
    {
    MessageBox("GoAway", "You have no permission to do that");
    }

    There are about 130 separate permissions and about 190 places in the application where permissions are checked ... what an exciting way to spend Friday.

    by Evgeny

    Now Reading

    "Peopleware: Productive Projects and Teams (Second Edition)"

    Great book. I won't try writing a review since there's plenty of them on the Internet. It's probably the most interesting book on managing software projects since

    "The Mythical Man-Month: Essays on Software Engineering"

    (I don't read much on the subject anyway, so I could have missed a few dozens of good books).

    Well after doing some reading, I learned a couple of things: my workspace is designed in the most counter-productive way possible and the project I am currently working on has all chances of joining those 25% of software products that are never actually used.

    Mood: insanely optimistic.

    by . Also posted on my website

    Tuesday, September 30, 2008

    My Favourite Anonymous Delegate

    Just to test out the editing capabilities here, I'll display a bit of code I use often.
    Let's say I have a business entity class to keep some data.


    public class MyBusinessEntity
    {
    public string MyProperty = string.Empty;
    }

    I keep these business entities in a List


    List listToSearch = new List();
    // fill the list with actual data

    I need to select all business entities that satisfy to a certain criteria.

    List listIFound = 
    listToSearch.FindAll(delegate(MyBusinessEntity entity)
    {
    return (entity.MyProperty == "myTestString");
    });

    listIFound will now contain all instances of MyBusinessEntity from listToSearch where MyProperty equals "myTestString".

    by . Also posted on my website

    Monday, September 29, 2008

    Good Deed For The Day

    Everyone seems to have a blog these days. If you don’t have a blog, you should at least read heaps of other people’s blogs. Otherwise you might as well live in a stone age. So, what would be the fastest way to become much more advanced, much more Web 2.0 compatible in the shortest period of time today? Create your own blog. Here we go. Tick.
    by . Also posted on my website