This has nothing to do with manual image creation, but is a feature of TSpeedbutton. As I explained above TSpeedbutton can contain up to 4 images in the Glyph property, each one reserved for a specific state. These 4 images are arranged in a stripe, side by side. When an image is loaded into the Glyph property the component checks whether the image width is an integer multiple of the image height. If this is the case then TSpeedbutton assumes that the image is such a multi-image stripe and displays only first image of the stripe; of course, this image has Width=Height. The NumGlyphs property is automatically set to the result of this division. You can check this when you add
Caption := IntToStr(SpeedButton1.NumGlyphs);
to the "MakeGlyph" procedure of your demo (after "Speedbutton1.Glyph := BM").
You can avoid this automatism if you force
SpeedButton1.NumGlyphs := 1;
immediately after "SpeedButton1.Glyph := BM".
There is a bug in TSpeedbutton by the way because this calculation obviously is not performed at designtime when a "double image" is assigned to Glyph. This is in contrast to Delphi as I just checked.