Click here to Skip to main content
15,881,715 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
RGB macro is defined in WinGDI.h header file as follows:
C++
#define RGB(r,g,b)      ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))


Please Need help. I know how to use this macro, but I don't understand the declaration of it. Learning it may be helpful. Please Need a step by step answer !

Thanks.
Posted

It's simply a macro to pack the 3 colour values into a 32 bit piece of memory.

Just look-up the bitwise operators << (shift left) & >> (shift right)

It takes byte/char sized inputs and returns a 32 bit var, formatted thusly:

00000000BBBBBBBBGGGGGGGGRRRRRRRR

Its the R value, ORed with the G value shifted left 8 bits, ORed with the B value shifted left by 16 bits

000000000000000000000000RRRRRRRR
0000000000000000GGGGGGGG00000000
00000000BBBBBBBB0000000000000000

00000000BBBBBBBBGGGGGGGGRRRRRRRR
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 16-Aug-12 16:06pm    
Explained. My 5.
--SA
enhzflep 16-Aug-12 21:49pm    
Thank-you. :)
pasztorpisti 16-Aug-12 17:08pm    
Got your 5 for the drawing :-)
enhzflep 16-Aug-12 21:49pm    
:laughs:
Thank-you. :)
Captain Price 17-Aug-12 2:43am    
thanks, short and nice.
It creates a "24 bit color reference" in 32 bit integer / unsigned in the form of "0x00bbggrr"

Red is the low 8 bits (0-7), Green is the next 8 bits (8-15) and Blue is the next 8 bits (16-23).

All the "typcasting" is to instruct the compiler how to do the math (shifts) on the values. The parenthesis around (r), (g), and (b) is so you can use an "expression" as the argument and it will be treated properly.

It might be a fun exercise for you to spread this statement out and slowly remove the sub-expressions to see how the parenthesises (parenthesii?) wrap the pieces to be evaluated by the compiler. Then it might make more sense to you.

One last thing, for "#define" macros, parenthesis are used to provide clarity to the compiler, which, ironically, removes clarity for the human (you).
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 16-Aug-12 16:07pm    
One more explanation, a 5.
--SA
pasztorpisti 16-Aug-12 17:09pm    
5ed because this gives some explanation on the brackets around the macro parameters.
It just composes a 32-bit value from the three components r, g, and b. Here is it step by step. First let's take the outer parentheses and cast to COLORREF away:

(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))


The r value is just reduced to 8-bits by the cast to BYTE and copied into the lower 8 bits:

(BYTE)(r)


The green value is also masked by its lower 8 bits, then cast into 16-bits (which is unnecessary) and shifted 8 bits to the left so that the green component now occupies bits 8...15:

((WORD)((BYTE)(g))<<8)


Both components are bitwise or-ed together:

((BYTE)(r)|((WORD)((BYTE)(g))<<8))


Finally the blue values is masked to 8 bits, cast up to 32-bit (again unnecessary) and shifted 16 bits to the left such that the blue component occupies now bits 16...23:

(((DWORD)(BYTE)(b))<<16)


Then it's combined to the red and green combined value that we did in the previous step. So we end up with

red:   bits 0...7
green: bits 8...15
blue:  bits 16...23


Easy, wasn't it.
 
Share this answer
 
v2
Comments
pasztorpisti 16-Aug-12 15:02pm    
+5, but you made a mistake here: "The green value is also masked by its lower 8 bits, then shifted 8 bits to the left and all that is cast into a WORD, i.e. a 16-bit value"
Actually the cast to word is done before the shift. Same is true for the cast to DWORD, casting is before shifting. The cast to word is totally unnecessary because the << operator always casts the shiftable type to int if its a narrower type than int (casts signed int even if the narrower type is unsigned) and an int is always at least 16 bit.
Sergey Alexandrovich Kryukov 16-Aug-12 16:07pm    
Ah... yes, good points.
--SA
nv3 16-Aug-12 16:12pm    
Your are so right. The cast has higher precedence than the shift operation. And yes, it's totally unnecessary. Thanks!

I have corrected the solution, so nobody accidentally repeats my mistake.
Sergey Alexandrovich Kryukov 16-Aug-12 16:07pm    
Agree, a 5.
--SA
nv3 16-Aug-12 17:33pm    
Thanks, Sergey!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900