Mike - question about Gradients Demo and 16bit colors

Mike - question about Gradients Demo and 16bit colors

Post by Mike D Sut » Fri, 17 Sep 2004 23:28:07


Hi Andy,


The library passes all input colour values through the EvalCol() method, which sends any system colour references through the
GetSysColor() API call. I've tested it here on a WinXP machine running at 16-bit and can't see a problem here, so perhaps it's a
WinME thing. Unfortunately I don't have a WinME machine available to test with so I can't give you much help there, but do some
testing and see what it (And to a degree EvalCol()) comes back with.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: XXXX@XXXXX.COM
WWW: http://www.yqcomputer.com/
 
 
 

Mike - question about Gradients Demo and 16bit colors

Post by Andy D » Sat, 18 Sep 2004 18:34:43

ike,

I tried to put together a few snapshots to show you but it get's trickier.
It turns out that a snapshot taken in 16bit mode won't show any difference
if seen on a 24/32bit system.
I guess the problem really lies in the way Windows handles color output when
in < 24bit mode.

I checked and the EvalCol function isn't the problem.
I'm guessing that the RGB break down that takes place in the NewTriVertex
function somehow has to be able to mimic this Windows limitation.

Here's a little code snippet based on your Gradients Demo.
To really see any issues though you're gonna have to run it on Win98/ME in
65536 color mode.

' ******************************************
Option Explicit

Private Type TRIVERTEX
x As Long
y As Long
Red As Integer
Green As Integer
Blue As Integer
Alpha As Integer
End Type
Private Type GRADIENT_RECT
UpperLeft As Long
LowerRight As Long
End Type
Private Type Guid
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Type PicBmp
Size As Long
type As Long
hBmp As Long
hPal As Long
Reserved As Long
End Type

Private Declare Function GetDesktopWindow Lib "user32.dll" () As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As
Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc
As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long,
ByVal hObject As Long) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long,
ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As
Long
Private Declare Function GradientFill Lib "msimg32.dll" (ByVal hdc As Long,
ByRef pVertex As TRIVERTEX, ByVal dwNumVertex As Long, ByRef pMesh As Any,
ByVal dwNumMesh As Long, ByVal dwMode As Long) As Long
Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As
Long
Private Declare Function OleCreatePictureIndirect Lib "OLEPro32.dll"
(PicDesc As PicBmp, RefIID As Guid, ByVal fPictureOwnsHandle As Long, IPic
As IPicture) As Long
Private Declare Function GetDeviceCaps Lib "gdi32.dll" (ByVal hdc As Long,
ByVal nIndex As Long) As Long

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1
Private Const BITSPIXEL As Long = 12

Private Function MakeFadePicture(lCol1 As Long, lCol2 As Long, pxWidth As
Long, pxHeight As Long, FadeHorizontal As Boolean) As StdPicture
Dim lDC As Long
Dim lBmp As Long
Dim hDesk As Long, DCDesc As Long
Dim lOldBmp As Long

' Fading picture creation

' Get the desktop DC
hDesk = GetDesktopWindow
DCDesc = GetDC(hDesk)
'Create a device context, compatible with the screen
lDC = CreateCompatibleDC(DCDesc)
'Create a bitmap, compatible with the screen
lBmp = CreateCompatibleBitmap(DCDesc, pxWidth, pxHeight)
'Select the bitmap into the device context
lOldBmp = SelectObject(lDC, lBmp)
' Fill DC with gradient colors
DrawRectGrad lDC, NewTriVertex(0, 0, lCol1), NewTriVertex(pxWidth,
pxHeight, lCol2), FadeHorizontal
' Create picture
Set MakeFadePicture = PictureFromBitmap(lBmp)
' Clean up
ReleaseDC hDesk, DCDesc
SelectObject lDC, l
 
 
 

Mike - question about Gradients Demo and 16bit colors

Post by Mike D Sut » Sun, 19 Sep 2004 02:43:27

Hi Andy,

<code snipped>

Why do people insist on re-posting my code back to the groups? - Please just include the libraries, that's what they're there for!
I'm now running a WinME virtual machine under VirtualPC in 16-bit mode both in the emulator and for the host system and I don't see
any problems with the output here..
I've occasionally found some problems using the byte splitting method used in the library (only ever one off though) so you may want
to try this version instead:

'***
.Red = HighByteWord(UseCol And &HFF&)
.Green = HighByteWord(((UseCol And &HFF00&) \ &H100&) And &HFF&)
.Blue = HighByteWord(((UseCol And &HFF0000) \ &H10000) And &HFF&)
.Alpha = HighByteWord(((UseCol And &HFF000000) \ &H1000000) And &HFF&)
'***

Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: XXXX@XXXXX.COM
WWW: http://www.yqcomputer.com/
 
 
 

Mike - question about Gradients Demo and 16bit colors

Post by Andy D » Sun, 19 Sep 2004 18:19:32

Mike,

sorry about the code reposting, I had no idea about your policies, my
apologies.

I uploaded a couple of screenshots taken under Win 98 (5kb):
http://www.yqcomputer.com/
Again, it's probably not gonna show much difference on a non-Win98/ME 16 bit
system.
You might be able to get some info by analizing the pixels with a photo
editor app.

In any case, I slightly modified the code:

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single,
Y As Single)
Me.Caption = Hex(GetPixel(Me.hdc, X, Y))
End Sub

Private Sub Form_Load()
' Create an stdPicture
Me.PaintPicture MakeFadePicture(vbButtonFace, vbButtonFace, 100, 100,
True), 0, 0
Me.ScaleMode = vbPixels
End Sub

On the screenshots you'll see the results: a form pixel is always reported a
&HC0C0C0 both in 24 and 16 bit modes; a pixel in the FadePicture area gets
reported as &HC0C0C0 in 24 bit mode and &HC8C8C8 in 16 bit mode (on a second
machine I got &HC8C4C8), which makes
the difference in the visible results.

Here's another odd thing that I hope can give you an idea of what's going
on:
If the form is displayed while in 16 bit mode and then the setting is
switched to 24 bit mode the color difference will go away;
If the form is displayed while in 24 bit mode and then the setting is
switched to 16 bit mode the color difference won't show up.
Meaning that apparently something gets calculated differently depending on
the settings, rather then being a painting problem.

I hope it's all clear and that you get a chance to try it out on a 98/ME
machine since I'm starting to wonder myself if it's a real problem or it's
just my eyesight going bad...

Thanks Mike,

--
Andy,

andreaATdstudio32DOTit
 
 
 

Mike - question about Gradients Demo and 16bit colors

Post by Mike D Sut » Mon, 20 Sep 2004 07:37:19

gt; sorry about the code reposting, I had no idea about your policies, my

Not a problem, just prefer to keep the libraries in one place rather than having lots of semi-complete old versions floating around.

<code snipped>

This looks to me like the first machine is running a 5:5:5 display mode, where as the second is running a 5:6:5 mode.
It's a little odd though since 0xC0 should be unchanged on either modes since it's lower 3 bits are unset which are the ones that
get chopped in the high colour conversion (0xC0 = 11000000b)


I think the problem is that GetSysColor() returns different values depending on the OS and display depth, here's what I get here
running under WinXP and WinME (Emulated.)
Both machines running a slightly modified version of the "Rainy day" colour theme - Hey, I'm in the UK, it seemed appropriate at the
time!

***
WinME 16 WinME 32 WinXP 16 WinXP 32 Name
0xD8CCC0 0xD8CCC0 0xD9CCC1 0xD9CCC1 - Scrollbar
0x806450 0x7C654E 0x7D654F 0x7D654F - Background *
0x000000 0x000000 0x000000 0x000000 - Active caption
0x806450 0x7C654E 0x7D654F 0x7D654F - Inactive caption *
0xB09880 0xB09880 0xB19983 0xB19983 - Menu
0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF - Window
0x000000 0x000000 0x000000 0x000000 - Window frame
0x000000 0x000000 0x000000 0x000000 - Menu text
0x000000 0x000000 0x000000 0x000000 - Window text
0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF - Caption text
0xB09880 0xB09880 0xB19983 0xB19983 - Active border
0xB09880 0xB09880 0xB19983 0xB19983 - Inactive border
0x7C654E 0x7C654E 0x808080 0x808080 - App workspace
0x786450 0x786450 0x7D654F 0x7D654F - Highlight
0xFFFFFF 0xFFFFFF 0xFFFFFF 0xFFFFFF - Highlight text
0xB09880 0xB09880 0xB19983 0xB19983 - Button face
0x806450 0x7C654E 0x7D654F 0x7D654F - Button shadow *
0x806450 0x7C654E 0x7D654F 0x7D654F - Gray text *
0x000000 0x000000 0x000000 0x000000 - Button text
0xD8CCC0 0xD9CCC1 0xD9CCC1 0xD9CCC1 - Inactive caption text *
0xD8CCC0 0xD8CCC0 0xD9CCC1 0xD9CCC1 - Button highlight

* = Changed
***

Booting/switching between 16 and 32 bit under WinME doesn't seem to make a difference to the output here, but this may be a side
effect from the emulator since they're both technically running under a WinXP display driver.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: XXXX@XXXXX.COM
WWW: Http://www.mvps.org/EDais/