Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C Windows Win32
RGB macro is defined in WinGDI.h header file as follows:
#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 16-Aug-12 7:40am
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 16-Aug-12 16:06pm
   
Explained. My 5.
--SA
enhzflep at 16-Aug-12 21:49pm
   
Thank-you. :)
pasztorpisti at 16-Aug-12 17:08pm
   
Got your 5 for the drawing :-)
enhzflep at 16-Aug-12 21:49pm
   
:laughs:
Thank-you. :)
Pravinda Amarathunge at 17-Aug-12 2:43am
   
thanks, short and nice.
enhzflep at 17-Aug-12 2:59am
   
You're welcome. :-)
Pravinda Amarathunge at 18-Aug-12 7:51am
   
Hey, Can you write a macro for me. ---- I want to store 2 numbers in an int. I need a macro to extract those 2 values from the int, and to set the the 2 values to an variable of type int. It'll be nice !
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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).
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 16-Aug-12 16:07pm
   
One more explanation, a 5.
--SA
pasztorpisti at 16-Aug-12 17:09pm
   
5ed because this gives some explanation on the brackets around the macro parameters.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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.
  Permalink  
v2
Comments
pasztorpisti at 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 at 16-Aug-12 16:07pm
   
Ah... yes, good points.
--SA
nv3 at 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 at 16-Aug-12 16:07pm
   
Agree, a 5.
--SA
nv3 at 16-Aug-12 17:33pm
   
Thanks, Sergey!
Pravinda Amarathunge at 17-Aug-12 2:43am
   
Well, good one, the thing is i'm not familiar with this (<<) thing.
nv3 at 17-Aug-12 3:22am
   
This (<<) thing is the shift operation.
 
See for example: http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_C.2C_C.2B.2B.2C_C.23.
Pravinda Amarathunge at 18-Aug-12 7:49am
   
yep, as it seems to be one of the Bit-wise operators in C.

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 643
1 OriginalGriff 550
2 CPallini 415
3 George Jonsson 231
4 ChauhanAjay 150
0 OriginalGriff 5,450
1 CPallini 4,500
2 Sergey Alexandrovich Kryukov 4,032
3 George Jonsson 3,057
4 Gihan Liyanage 2,445


Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 16 Aug 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100