CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.
  • Dave Laribee Video Coverage of Mix08

    Just a quick administrative note, as this information is timely and not to be missed.

    Dave Laribee is our man at Mix08 and is doing some great Qik.com videos with the CodeBetter Video Phone (Nokia N82)... Be sure to check it out, and if you'd like to get in front of the camera to say hi, try to hook up with Dave.

    • Rob Connery, Steve Harman @ MIX08 Rob Connery, Steve H... about 15 hours ago
    • Miguel de Icaza @ MIX08 Miguel de Icaza @ MI... about 15 hours ago
    • Pablo Castro @ MIX08 Pablo Castro @ MIX08 about 17 hours ago
    • John Lam @ MIX08 John Lam @ MIX08 about 17 hours ago
    • Microsoft Surface @ MIX08 Microsoft Surface @ ... about 18 hours ago
    • Josh Holmes @ MIX08 Josh Holmes @ MIX08 about 18 hours ago
    • MIX08 - Keynote MIX08 - Keynote about 21 hours ago

    ...Now back to our regularly scheduled program.

  • New Ajax-Enabled CAPTCHA for Community Server 2007

    Just a quick post to announce the release of the latest version of CodeBetter.CommunityServerExtensions which includes some bugfixes and the much anticipated CAPTCHA validation on the server via Ajax stuff.

    I knew it was time when I started getting comments like this to the original announcement:

    sorry brendan, using a cookie to store the captcha code sucks.

    and "probably not something that a spammer would be motivated to do.." would maybe be true of you had written your own proprietary system, but this being the best available captcha control for cs 2007 ... come on.

    jacob

    The previous solution did rely on the CAPTCHA text being stored in a cookie, which was an easy way to enable the validation at the browser.  I had always maintained that a spammer wouldn't be motivated to write the code to break the CAPTCHA in this implementation, but it was breakable.  Jacob was right about the sucking part, but it *did* work pretty well to kill comment spam.  The new version will allow you to use AJAX to validate the CAPTCHA on the server. It's a much better solution.

    There are some other bugfixes too, including support for forum posts as well.

    You can get the dll and source code here *.

    * Latest Version - 1.1 December 5, 2007
  • ASP/ASP.NET MVP!

    Got the word yesterday that I received an MVP award for "Visual Developer - ASP/ASP.NET" ...

    I'm going to be spending the next few weeks brushing up on my ASP skills, because as an MVP I surely must be expected to know these things. 

    Thanks to Raymond for the nomination this year, Sahil for the nomination last year and all the other folks for the support.

    Now, where did I put those include files again? .. hmm.


     

  • Refactoring Unsafe Code: GIF Image Color Quantizer, Now with Safe Goodness

    I've had a few requests to create a safe version of the Image Quantization library I've blogged about quite a few times: see Use GDI+ to Save Crystal-Clear GIF Images with .NET.  It turns out this is quite useful for a lot of people, but the old version contained unsafe code, which wouldn't run under medium trust with .NET 2.0.

    I spent a few hours yesterday creating a safe version of this library.  The re-factoring process was fun, and I found a few cool things you can do with Marshal class with .NET. 

    Incrementing IntPtrs

    I didn't know you could do this, and there's probably going to be situations where this doesn't work, but provided you have used something like the Bitmap's LockBits method to lock the bits into system memory, you can increment an IntPtr like so:

    IntPtr pSourcePixel;

    pSourcePixel = (IntPtr)((long)pSourcePixel + _pixelSize);


    Pointers To Structures

    Never knew about this either, but if you can map a structure to memory by using the Marshal.PtrToStructure method.

    (Color32) Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

     

    ... where Color32 is a structure that looks like this specifying FieldOffset, and pSourcePixel points to a 32-Bit color value

     

    [StructLayout(LayoutKind.Explicit)]

    public struct Color32

    {


        [FieldOffset(0)]

        public byte Blue;


        [FieldOffset(1)]

        public byte Green;


        [FieldOffset(2)]

        public byte Red;


        [FieldOffset(3)]

        public byte Alpha;

     }

     So, in the end, a method that looked like this (unsafe)

    /// <summary>

    /// Execute the first pass through the pixels in the image

    /// </summary>

    /// <param name="sourceData">The source data</param>

    /// <param name="width">The width in pixels of the image</param>

    /// <param name="height">The height in pixels of the image</param>

    protected unsafe virtual void FirstPass ( BitmapData sourceData , int width , int height )

    {

        // Define the source data pointers. The source row is a byte to

        // keep addition of the stride value easier (as this is in bytes)

        byte*    pSourceRow = (byte*)sourceData.Scan0.ToPointer ( ) ;

        Int32*    pSourcePixel ;

     

        // Loop through each row

        for ( int row = 0 ; row < height ; row++ )

        {

            // Set the source pixel to the first pixel in this row

            pSourcePixel = (Int32*) pSourceRow ;

     

            // And loop through each column

            for ( int col = 0 ; col < width ; col++ , pSourcePixel++ )

            // Now I have the pixel, call the FirstPassQuantize function...

            InitialQuantizePixel ( (Color32*)pSourcePixel ) ;

     

            // Add the stride to the source row

            pSourceRow += sourceData.Stride ;

        }

    }

    Was refactored to this:

    /// <summary>

    /// Execute the first pass through the pixels in the image

    /// </summary>

    /// <param name="sourceData">The source data</param>

    /// <param name="width">The width in pixels of the image</param>

    /// <param name="height">The height in pixels of the image</param>

    protected  virtual void FirstPass(BitmapData sourceData, int width, int height)

    {

        // Define the source data pointers. The source row is a byte to

        // keep addition of the stride value easier (as this is in bytes)             

        IntPtr pSourceRow = sourceData.Scan0;

     

        // Loop through each row

        for (int row = 0; row < height; row++)

        {

            // Set the source pixel to the first pixel in this row

            IntPtr pSourcePixel = pSourceRow;

     

            // And loop through each column

            for (int col = 0; col < width; col++)

            {           

                Color32 color = (Color32) Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

                // Now I have the pixel, call the FirstPassQuantize function...

                InitialQuantizePixel(color);

                pSourcePixel = (IntPtr)((long)pSourcePixel + _pixelSize);

            }   

     

            // Add the stride to the source row

            pSourceRow = (IntPtr)((long)pSourceRow + sourceData.Stride);

        }

    }

    So, get the new improved, safe version of the image quantizer here, and the source code here.

  • Lazy Friday Thoughts on Addictive Technology

    There's something in me that's generally skeptical about new technology. Recently I've been trying to understand why I'm slightly under-whelmed by Silverlight.   On the face of it, having a truly cross-platform CLR sounds absolutely incredible.  I've invested the last 6 years of my career and the majority of my coding for the CLR, why am I not jumping up and down for joy?

    I think it might be because what's really exciting to me these days are these addictive technologies like Twitter, that you can create with very simple very thin client techniques that don't require something like Silverlight to work.  Perhaps this is where I'm not quite seeing the (silver) light.  To really try to sort out what goes into an addictive application, I'm trying to explore whether or not addictive technologies have things in common.  I think they do This blog post continued over on my twitter account:

    .... 

    A final thought about Addictive Technology is that it helps if it's mobile.  If I can't do it on my phone at a stoplight, I'm not going to become addicted.  Silverlight is just one more thing I need to be sitting down at my desk for.

    -Brendan 

  • CAPTCHA for Community Server 2007

    I'm happy to announce that CodeBetter.Com is carrying on the legacy of CAPTCHA for Community Server.  CAPTCHA for CS2007 is the next generation of CS Guru Dave Burke's most excellent CAPTCHA control for Community Server 2.1This version is implemented as a Control Adapter which allows CAPTCHA to be added to Community Server site-wide without touching any ASPX or ASCX markup code.

    You can get the dll and source code here *.

    * Latest Version -  April 29th 2007

    IMPORTANT NOTE:  If the form in your ASPX control specifies a validation group, your controls must also specify the same group. Some skins that ship with CS2007 have a validation group specified for the form, but not for the controls.  The CAPTCHA control will not work for these forms.  To fix, either remove the validation group from the form code or add to all of your form's controls.

     EX:  Form specifying a validation group:

                    <CSFile:CreateEntryCommentForm runat="server"
                            MessageTextBoxId="CommentBody"
                            NameTextBoxId="CommentName"
                            RememberCheckboxId="CommentRemember"
                            SubjectTextBoxId="CommentTitle"
                            SubmitButtonId="CommentSubmit"
                            UrlTextBoxId="CommentWebsite"
                            ControlIdsToHideFromRegisteredUsers="RememberWrapper,AnonymousUser"
                            ValidationGroup="CreateCommentForm"
                        >

     Must also specify the validation group in the controls to be validated:

  • CodeBetter.Com Community Server 2007 Upgrade!

    If you're a regular visitor.  You may have noticed that today CodeBetter.Com has a new site skin.   Hopefully this skin is better to look at, and loads faster than our old ugly digs.

    I'm happy to report that we're up and running on Telligent's Community Server 2007,  which was released earlier this week.   If you're a CS user, you've got to check out this version.  The codebase has come leaps and bounds since the last release, with all sorts of goodness in the skinning and template departments.  It was such a pleasure to code this latest version of CodeBetter with the new bits.  All the guys over there deserve a big pat on the back.

    One of the controls that I could not go live with with this latest version was Dave Burke's outstandingly fabulous CS CAPTCHA control for comment spam filtering.  His version was for CS 2.1, so I had some coding to do to get this working. I'm happy to report that I've built a version that can be deployed with CS 2007, and the first chance I get I'll release the source and blog about it here.  Dave's asked me to release it, so I guess CodeBetter will be the new home for this control.

    (p.s. I know we have 45 validation errors, and I'm working on it!)

  • An Open Source Translation Dictionary for Windows Mobile

    Over at Devlicio.us I'm blogging about my experiences developing an application for my Samsung Blackjack:

     

    samsung_i607.jpg


     
    It's a Translation Dictionary with a Flashcard feature that supports multiple dictionaries, with the ability to create and more. Currently I'm packaging an English-French dictionary with over 16,000 Entries, and an English-Spanish dictionary with over 10,000.  There's over 1,000 Flashcards of common words in each Dictionary. Each term is hyperlinked when it appears in a definition. It's absolutely free and open source.

    Here's a screenshot:



    I'm going to blog about and release the dictionary loader with more dictionaries as soon as I can get some time. 

    Downloading and Installation

    "Translation Dictionary v 0.1" is optimized and designed for Windows Mobile.  Get it and the source code for the application it here: 

  • Edit SQL 2005 Analysis Server Cube Report Models

    I've been spending a good portion of the year so far working with SQL Server 2005.   I have to comment that when Microsoft hits the mark with a product release, they really nail it.   With SQL 2005 and all of its component services, they've created a hugely powerful suite of servers. It's been well worth my time spent learning this new tool set.

    The learning curve is steep, however, and there have been numerous times where I have been stumped with problems integrating the various tools, setting up servers, and using "SQL Server Business Development Studio" um.. Sorry Visual Studio.

    One of my goals has been to create a Report Model that will simplify the ability for end users to create reports.  If you're not familiar with how Report Models make Reporting Services easier to use, watch this webcast: End-User Ad Hoc Reporting with SSRS (Level 300)

    Here was my problem.  After creating a report model from my cube (using the auto-generate feature of SSMS or Reporting Services)  the model really wasn't usable.  Click-through entities weren't setup properly, naming was not right, and there were a lot of fields I didn't want the end-user report writers to see.. It was a start, but not deployment ready.

    I was unable to use Visual Studio's support for report model projects to let me create a model from an Analysis Server Cube... This functionality seems to be absent from this release, or at least wouldn't work with my installation.  I did manage, in a round about way to edit my generated report models in Visual Studio: Here's what I did:

    Step 1: Add A Report Model Project to your Solution:

    The key to getting this to work was to add a Report Model Project to my solution which already contained my Analysis Server Project.  Copy the Data Source and Data Source View from your SSAS project to your Report Model Project.  This is important! Without the same named Data Source View and Data Source, your won't be able to import this report model.

     

    Step 2: Export and Add your Generated Report Model (.smdl)  to your Project 

    You can use SSMS or the Reporting Services web interface to do this.  I found it easier to do this in SSMS by Right-Clicking the Model and selecting Edit.

     

    Import this model into your new Report Model Project, and you should be able to edit all of the entities:

     

    Step 3: Import  the Model back into SSRS, using SSMS.

    DO NOT publish your model back to the server using Visual Studio.  This will add some schema information to your model, and it will no longer function against your cube in Reporting services.  The key here is to use SSMS to "Import File" and import your edited .smdl model back into SSRS.



    Step 4. Re-Configure the Model's Data Source

    The final step is to re-set the data source back to use the Analysis Server Cube. You'll notice that the newly imported data model has an invalid data source.  Select the original cube data source:

    Once you've done this, your new model should work against your Cube, and will provide your end-user report writers a customized Model of your data.  Over time, as you customize your Cube, you will have to re-generate a model from the cube, and migrate the changes into your production report model file by hand. You'll find that this can be done using a diff tool quite easily, since the .smdl file is XML.

  • Funny Error Message

    While unfruitfully plodding my way through creating an OLAP cube with SSAS 2005, I saw this error today which made me chuckle:

    "If you see this there was a major bug while creating object Dimension"

    Is this the coding  equivalent of the "If you can read this, you're too close" bumper stickers?

     

  • Book Giveaway - Final Winner

    Congratulations to the final winner of The Great CodeBetter Eight-Week Fall Book Giveaway,  Miguel Jimenez Antelo.

    Miguel gets a copy of : 

    Essential ASP.NET 2.0

    Essential ASP.NET 2.0
    By Fritz Onion, Keith Brown.

    We'll be getting some more books to give away, and next time, I promise to make the contest more interesting. Embarrassed If anyone has any good ideas, let me know.

    -Brendan
     

  • GIF Image Color Reduction in .NET

    A while back, I posed a solution for creating an adaptive GIF image from a JPEG image source in .NET, Use GDI+ to Save Crystal-Clear GIF Images with .NET

    Recently a question was asked in the comments about how to save a 16-color GIF image using this library. It's pretty simple actually, in fact, here's the code:

       13             Image img = Image.FromFile("original_image.gif");

       14             OctreeQuantizer quantizer = new OctreeQuantizer(15, 4);

       15             using ( Bitmap quantized = quantizer.Quantize ( img ) )

       16             {

       17                 quantized.Save("new_image.gif", ImageFormat.Gif);

       18             }
     

    The OctreeQuantizer class' constructor takes two parameters, the size of the color array (zero-based) and the bitdepth of the image.  You can use this to create an image with varying palette sizes.

    I thought that a quick downloadable example project would be in order, since there seems to be a lot of interest in saving gif images with adaptive palettes in .NET.

    See this post here for the latest on this project 

  • Book Giveaway - Week 7 Winner

    Congratulations to Week 7 winner Keith Rull!  Keith runs Devpinoy.Org, a Filipino Developers Community... definitely check it out. Keith gets a copy of Data Structures and Algorithms in Java, 2nd Edition by Robert LaFore.

    Data Structures and Algorithms in Java, 2nd Edition
     
    One more week left, and it's a doosey!
     
    More about The Great CodeBetter Eight-Week Fall Book Giveaway here.
  • Book Giveaway - Week 6 Winner

  • CodeBetter.Com Breaks the 5 Digit Bloglines Subs Barrier!

    I've been waiting for this for a while now, but today, CodeBetter.Com has reached 10,000 Bloglines subscriptions!  Just wanted to say congratulations to the CodeBetter.Com guys for the great blogging that's gotten us here, and to everyone who participates in this community!

More Posts Next page »

Our Sponsors

Free Tech Publications