Saturday, October 25, 2003

Switched to dasBlog

Well I did it!  I went ahead and switched to dasBlog.  Radio finally drove me to the brink and I needed some new software in time for the PDC.  I must admit I really wished it supported hosting multiple blogs in a more flexible fashion but it is pretty amazing how easy the transfer was from Radio.  I looked at .Text but most folks I know are running dasBlog and they claimed the Radio transition was fairly painless.  More posts coming next week from the PDC...

Saturday, October 25, 2003 11:38:52 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Wednesday, September 24, 2003

More Compact Framework Thoughts

More Compact Framework Thoughts

Wow!  Two posts in one day.  Considering the dearth of posts from this blog lately that is pretty amazing. After my earlier rant I remember something I brought up with the CF team at Microsoft.

When I have heard the limitations of CF described in the past by MS folks it has been in the context of, "We are running on smaller, memory constrained devices so we built a smaller version of the framework that fits in just 2 MB."  That is all well and good but I am starting to do work for Windows CE based devices with 128MB and 256MB and I really want the full power of the framework.  While it is impressive that they were able to compress the amount of goodness that they did into 2 MB but what about developers for which there is abundant memory available?  Why didn't the team take more of a factored approach such that if I was willing to give them another 2MB I could get remoting or <insert your favorite dropped feature here>?

This really brings to life the promise of only needing to know how to develop for one platform, .NET.  I don't need to know a long laundry list of limitations of things that I can't do on WindowsCE.  Instead I have to be willing to step up and trade RAM for features.  I know, I know not all features will be available on WindowsCE because of limitations of the OS.  I am fine with that.  The list of things removed due to OS limitations is going to be much shorter than the current list of things that were removed.  IOW the delta between desktop and compact will narrow but not necessarily close the gap.

Wednesday, September 24, 2003 2:26:51 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 
Compact Framework Rant

Compact Framework Rant

I admit it.  I have been doing a considerable amount of Compact Framework programming over the last couple of months. First off let me say I think Compact Framework hold great potential.  That being said I think it has a long way to go.

I recently build two applications using the compact framework.  One was a kiosk style application that had to communicate with other controller programs running on the kiosk.  This communication ended up happening using windows messages.  Luckily the MessageWindow class provides a way to receive messages however it is the only hWnd exposed so the applications I was communicating with had to do a FindWindow() on my forms to find their hWnds.  Ridiculous considering the hWnd is exposed off each windows form in the desktop framework.  Next problem we hit was that come to find out Windows CE has a 32MB process size limit!  Of course we were precaching a number of graphics, etc and even attempting to play video which meant that we hit this limit pretty quickly.  In a day when devices had 2-4 MB on average a 32MB process limit probably made sense.  Today however is it ridiculously small.  Next roadblock.  We needed to play animated GIFs.  They play in PocketIE so we figured no problem.  Wrong!  The animated gif support was ripped from the bitmap class in Compact Framework!  This of course meant that we needed to write our own animated GIF class.  Things were going fine until we were handling the dispose types for an animated GIF and realized that the lack of a way to XOR bitmaps was going to make the process very, very difficult.  Granted this is a limitation in the desktop framework as well as the compact framework.  Argghh!

Next we move on over to writing a PocketPC application where things go a bit smoother but we still find some frustrations.  It is intended to be a wireless application used as a specialized tool for a customer service person.  Sort of like the folks you see at the Hertz car rental places.  It talks to a backend database as well as a wireless 802.11b printer.  Of course the middle tier that is in place uses remoting which, you guessed it, the compact framework lacks.  So we wrapped access to the remoted interface with a web service.  Things are going along well once we get around this roadblock, until we test on the actual device.  We realize that we have written an application that has no way to bring up the SIP (soft input panel) on the device. Not a problem we say.  We can just place the SIP control on our form and use it to display the SIP.  Whoa!  We don't have a menu bar on our form and for some bizzarro reason the SIP will only work on forms with a menu bar!  So we figure out how to make the API call and draw a few lines to show a fully functional SIP on our form.

If you are interested here is how you show the SIP:

  [System.Runtime.InteropServices.DllImport("coredll.dll")]
  private static extern bool SipShowIM(int dwFlag);

To show it:

    SipShowIM(1);

To hide it:

    SipShowIM(0);

There is a bottom line missing on the SIP since it counts on the menu bar to draw it.  So add a:

e.Graphics.DrawLine(new Pen(Color.Black), 0, 294, 240, 294);

In the forms paint when the SIP is showing and you are all set.

Wednesday, September 24, 2003 12:39:37 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Friday, September 12, 2003

Are you happy Scott?

Are you happy Scott?

Scott Hanselman recently wrote an article about the difference between friends and acquaintances where he mentioned me.  Of course he also browbeat me about the fact that I hadn't posted anything recently on my blog. The last non-blogging stretch I had was due to Radio melting down but this time around I just have been insanely busy for the last couple of months.

Scott I have frequently asked myself the same question.  I frequently confuse the two terms calling acquaintances friends quite often. Friendship is a two way thing.  While I would have no problem at all with any of the acquaintances I call friends crashing at my place (if that is the criteria) I can't say that the feeling would be mutual. Not a problem for me. Still call them friends and my door is still open.  Scott you are of course welcome to crash at my place anytime.

It is almost at an end however and I am looking forward to getting back to normal.  I sit right now in a Hotel room in Orlando preparing for an all day workshop I am giving tomorrow on "Best Practices for Enterprise Development" with Rockford Lhotka. As I sit here preparing I can't help but remember a talk Scott, Bill Evjen and I had just today about the content at most conferences. Bill had just finished an intro to Web Services talk that was so well received it suprised him. He couldn't believe that almost three years after the release of the first .NET Web Services stack that folks were still interested in the basics. I then mentioned that I was doing a workshop tomorrow that was all new to me and quite honestly a new type of workshop for VSLive! which tends to be focused on very pragmatic code based talks. It is a talk that is really focused not on code but on the other things that need to go into a project to make it successful.  It is really pretty basic blocking and tackling but come to find out is the most popular workshop so far based on registrations! Just goes to show that what I find interesting isn't necessarily what my attendees will find interesting.  I think speakers get caught in a trap of creating content that they think their peers will find impressive instead of looking at the conference attendees and determining what is useful to them. Let's face it.  Most speakers wouldn't be at the conference if they weren't speaking.  They aren't the intended audience.  What do you think?

Hopefully this will not be my last post in a long while.  I have been doing quite a bit of Compact Framework development that has really given me a new perspective on .NET.  I really need to write down some of my experiences and hope to do so over the next couple of weeks.  First I have to finish my last conference of the season, Guided Design .SUMMIT on campus at Microsoft October 1-3. 

Friday, September 12, 2003 7:14:49 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Wednesday, June 18, 2003

New .NET Architecture List

New .NET Architecture List

I am starting a new list of Architecture links related to .NET.  I put it off for a long time until I was sitting with someone today trying to show them an architecture document from PAG and then couldn't find it for 15 minutes as I waded through the site.  The list will start out quite unordered.  Eventually over time I will impose more organization as it grows in size.

Wednesday, June 18, 2003 5:07:40 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]   .NET Architecture
 

  Thursday, June 12, 2003

.NET Posters

.NET Posters

Ever wanted one of those cool VS.NET object model posters you see on other developers walls? Have a 36" wide HP InkJet sitting unused down the hall since the last time you printed out that 1500 table ERD diagram? Well solve both problems with one link: http://msdn.microsoft.com/vstudio/productinfo/posters/download.aspx

Thursday, June 12, 2003 1:56:42 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Monday, June 09, 2003

Validation and Form Close

Validation and Form Close

Ran into a weird one today.  We have a windows forms application that uses the validating event on it's controls.  When the user clicks the close box (red x) in the corner we want to prompt whether they would like to save and then close the form.

The validators cause problems with this.  Clicking on the close box causes validation to run. First blush you think no problem, I will set CausesValidation on the form to false.  Whoa!  The Validating event still fires.  It appears that the close box always causes validation. Next you think I will override OnClosing() and ask whether they want to save before calling the base implementation thus only allowing the Validating events to fire if they are saving.  Wrong again.  Validating fires before OnClosing!

So here is the hack I came up with.  Override WndProc in the form and look for the WM_CLOSE message.  If you receive it then set a protected member on the form to indicate it is currently closing.  I have this hidden in a base class that exposes the member as a read only property.

Here is some sample code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace ValidationTest
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(80, 96);
            this.textBox1.Name = "textBox1";
            this.textBox1.TabIndex = 0;
            this.textBox1.Text = "textBox1";
            this.textBox1.Validating += new System.ComponentModel.CancelEventHandler(this.textBox1_Validating);
            // 
            // textBox2
            // 
            this.textBox2.Location = new System.Drawing.Point(80, 128);
            this.textBox2.Name = "textBox2";
            this.textBox2.TabIndex = 1;
            this.textBox2.Text = "textBox2";
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        // Constant for WM_CLOSE
        private const int WM_CLOSE = 16;
        // flag to indicate we are closing
        private bool m_bFormClosing = false;

        protected virtual bool FormClosing
        {
            get { return m_bFormClosing; }
        }

        private void textBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Bail out if the form is in the process of closing
            if(FormClosing)
                return;

            // Do my normal validation
            if(this.textBox1.Text == "invalid")
            {
                e.Cancel = true;
                MessageBox.Show("Invalid entry");
            }
        }

        protected override void WndProc(ref Message m)
        {
            // Check for the closing message
            if(m.Msg == WM_CLOSE)
                // Set our flag
                m_bFormClosing = true;

            // Call the base
            base.WndProc (ref m);
        }
    }
}

 

Wow that is ugly!  If anyone knows of a good C# -> HTML converter that works with Radio send me a pointer at mailto:ckinsman@vergentsoftware.com. This is from http://www.manoli.net/csharpformat/

Monday, June 09, 2003 6:58:19 AM (Pacific Standard Time, UTC-08:00)   #      Comments [1]  
 

  Monday, April 07, 2003

Managed Wrapper for BITS

Managed Wrapper for BITS

BITS is a pretty cool background transfer service that does the hard work of actually determining when your network connection is idle to transfer files. A managed wrapper for the API just became available on MSDN.

Monday, April 07, 2003 9:38:38 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 
Blast from the Past

Blast from the Past

Keith brings up writing certification exams for Microsoft.  We both did this for a while and became SMEs (Subject Matter Experts) in the terminology of the team at the time.  It was interesting to get some insight into the truly bizarre way that importance is assigned to topics in those tests.  The way correct answers were determined was sometimes even more bizarre.  One of the main reasons that I stopped the whole exam treadmill years ago. 

I still laugh when I remember back to arguing with Ken and Mike over whether or not Access questions should be on a Windows Architecture exam...

Sunday, April 06, 2003 11:49:56 PM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 

  Wednesday, March 26, 2003

.NET 1.1 Breaks ChainStream

.NET 1.1 Breaks ChainStream

Well we have been working hard on converting our 1.0 code base to 1.1.  We keep running into little things that are breaking our code though.  The latest is a breaking change in ChainStream.  We had a compression stream that we were running on top of our web services. In .NET 1.1 some new code (SoapServerProtocolHelper) was introduced that attempts to seek the stream closest to .NET without checking the CanSeek property.  Essentially what this means is that whereas non-seekable streams were legal in 1.0 they are no longer legal in 1.1.  Kind of kills some of the utility of ChainStream since it means that you pretty much have to buffer the whole request or figure out how to just buffer some of the envelope so you can seek back when requested. Here is the disassembly courtesy of Anakrino:

internal static SoapServerProtocolHelper GetHelper(SoapServerProtocol protocol) {

SoapServerMessage local0;

long local1;

XmlTextReader local2;

string local3;

SoapServerProtocolHelper local4;

local0 = protocol.Message;

local1 = local0.Stream.Position;

local2 = SoapServerProtocolHelper.GetXmlTextReader(local0.ContentType, local0.Stream);

local2.MoveToContent();

local3 = local2.NamespaceURI;

local4 = SoapServerProtocolHelper.GetHelper(protocol, local3);

local0.Stream.Position = local1;

return local4;

}

The killers are the lines that attempt to set the position...

Wednesday, March 26, 2003 12:45:04 AM (Pacific Standard Time, UTC-08:00)   #      Comments [0]  
 


Administration
Sign In