Win32 COLORREF vs .NET Color

I have been migrating a large application from Win32/MFC to .NET and ran into an interesting problem. We store all of the application colors in the database as integers that represent the Win32 COLORREF value. COLORREF is just a DWORD representing the RGB value, so I thought that I could just take the value and get a .NET Color structure using the static FromArgb method.

This didn’t go too well. It turns out that the byte orders are different. COLORREF is in the order 0x00bbggrr and Color is in the order 0xaarrggbb. Notice that the high order byte in .NET is the alpha channel, but in Win32 it is always zero (fully transparent in .NET) Also notice that the byte order is backwards in Win32, Blue/Green/Red compared to the more standard Red/Green/Blue in .NET.

We began by doing the conversion in code using a bit of bit fiddling;

<span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">static</span> <span style="color: rgb(128,0,128)">Color</span> ConvertFromWin32Color( <span style="color: rgb(0,0,255)">int</span> color )
{
   <span style="color: rgb(0,0,255)">int</span> r <span style="color: rgb(255,0,0)">=</span> color <span style="color: rgb(255,0,0)">&amp;</span> <span style="color: rgb(128,0,128)">0x000000FF</span>;
   <span style="color: rgb(0,0,255)">int</span> g <span style="color: rgb(255,0,0)">=</span> ( color <span style="color: rgb(255,0,0)">&amp;</span> <span style="color: rgb(128,0,128)">0x0000FF00</span> ) <span style="color: rgb(255,0,0)">&gt;&gt;</span> <span style="color: rgb(128,0,128)">8</span>;
   <span style="color: rgb(0,0,255)">int</span> b <span style="color: rgb(255,0,0)">=</span> ( color <span style="color: rgb(255,0,0)">&amp;</span> <span style="color: rgb(128,0,128)">0x00FF0000</span> ) <span style="color: rgb(255,0,0)">&gt;&gt;</span> <span style="color: rgb(128,0,128)">16</span>;
   <span style="color: rgb(0,0,255)">return</span> <span style="color: rgb(128,0,128)">Color</span><span style="color: rgb(255,0,0)">.</span>FromArgb( r, g, b );
}

This worked well at first, but it was error prone converting between the values. As new code was written, we often forgot that we needed to convert. Finally we decided to do the right thing and convert the values in the database. To do this, I wrote a simple upgrade script for our SQL Server database that consisted of one method which was then applied to each column in the database that contained color values.

<span style="color: rgb(0,128,0)">-- =============================================
-- Author: Rob Prouse
-- Date: 15/08/07
-- Description: Convert control colors from 
-- </span>  <span style="color: rgb(0,128,0)">Win32 COLORREF (0x00BBGGRR) values to .NET 
-- </span>  <span style="color: rgb(0,128,0)">Color Values (0xFFRRGGBB)
-- =============================================
</span><span style="color: rgb(0,0,255)">CREATE </span>FUNCTION SwapColorBytes( @Color <span style="color: rgb(0,0,255)">int </span>)
RETURNS <span style="color: rgb(0,0,255)">int
AS
BEGIN
</span>   <span style="color: rgb(0,0,255)">RETURN </span><span style="color: rgb(128,0,128)">0xFF000000 </span>+ 
          ((@Color &amp; <span style="color: rgb(128,0,128)">0x00FF0000</span>)/<span style="color: rgb(128,0,128)">0x00010000</span>) + 
          (@Color &amp; <span style="color: rgb(128,0,128)">0x0000FF00</span>) + 
          (( @Color &amp; <span style="color: rgb(128,0,128)">0x000000FF</span>)*<span style="color: rgb(128,0,128)">0x00010000</span>)

<span style="color: rgb(0,0,255)">END
</span>GO

<span style="color: rgb(0,128,0)">-- Do the following for every column in the DB that contains colors</span>
<span style="color: rgb(0,128,0)"></span><span style="color: rgb(0,0,255)">UPDATE </span>mytable <span style="color: rgb(0,0,255)">SET </span>colorcolumn = SwapColorBytes(colorcolumn)
GO

2 thoughts on “Win32 COLORREF vs .NET Color

Comments are closed.