|
Would anyone provide sample source code on this topic?
|
|
|
|
|
How exactly do I get it to draw gray icons? I'm trying to draw icons the way toolbars draw disabled icons (see IE6 toolbar). What part/state am I supposed to call it with?
I've tried pretty much everything, and it still draws a non-gray icon.
--
...Coca Cola, sometimes war...
|
|
|
|
|
See DrawState and specify DSS_DISABLED.
- Jeremy
|
|
|
|
|
Ah yes, but it doesn't quite do it. Themed toolbars are grayed as in black and white when disabled. DSS_DISABLED embosses the image, which isn't quite what I want.
I will take a look at CxImage here on CP tomorrow. I think it has what I need.
--
...Coca Cola, sometimes war...
|
|
|
|
|
Check out DitherBlt from WTL then. It's in atlgdi.h.
|
|
|
|
|
Been there, done that.
If you take a look at the toolbar (coolbar/rebar or whatever microsoft calls it) in IE, you'll see what I mean. The icons are just desaturated. No 3D effects are applied at all. I don't think a simple blit will do the trick for me, unless you or someone knows a clever way to do it with XOR/AND/OR bitblt magic.
--
...Coca Cola, sometimes war...
|
|
|
|
|
Ok now I get it. IE does that by using grayscale bitmaps for the default image-list of the toobar and color ones for the hot-image-list. You set them using TB_SETIMAGELIST and TB_SETHOTIMAGELIST messages. I forget which DLL they're in, maybe comctl32, but if you look you'll find a set of bitmaps for each size, color and grayscale.
WinXP does mentions support for drawing icons in grayscale, but AFAK it's not supported. Other than that, GDI+ maybe?
|
|
|
|
|
JBoschen wrote:
WinXP does mentions support for drawing icons in grayscale, but AFAK it's not supported. Other than that, GDI+ maybe?
I found traces of such support in tmscheme.h (or was it tmschema.h?). I found a property called ...SATURATION..., which was documented with a comment mentioning icons. I did not find any corresponding parts/states though for actually drawing the bitmap. The function DrawThemeIcon() , just draws the image as if I had used ImageList_Draw[ex]() .
I did find a function in an article/project written by PJ Arends here on CP which has a function to grayscale bitmaps. I guess I could have a look at it tomorrow.
It's a damn shame I'm so clueless when it comes to image/color theory and advanced GDI. I guess I'll have to order a Petzold book.
--
...Coca Cola, sometimes war...
|
|
|
|
|
There are two formulas i've seen for calculating a grey value from an RGB :
1. byte grey = (R * 0.299) + (G * 0.587) + (B * 0.114);
2. byte grey = (R * 0.2126) + (G * 0.7152) + (B * 0.0722);
The first is what you will generally find documented. It is based on National Television Standard Committee (NTSC) findings from the 50's. It is based on how the human eye perceives light and tuned to how the color TV phosphour (50's) displays RGB colours.
Other sources say these values are no longer representative of current TV/monitor displays and state that the values in 2. should be used.
Regardless, for each pixel :
byte grey = <1 or 2>;
R = grey;
G = grey;
B = grey;
As you've found there are articles here on how to access/change the pixel values in a bitmap.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
Thanks for the 2 formulas, highly appreciated! I will test them both. Just for fun
cmk wrote:
As you've found there are articles here on how to access/change the pixel values in a bitmap.
I did find a function on the net earlier today which transforms an icon into a gray scale icon. I used the function and instered the gray scale icon into an image list. Unfortunately, the image list just wouldn't accept the icon's mask! I used PJ Arend's excellent icon/bitmap/dc debugger, and found that the icon renders perfectly when using DrawIcon. Unfortunately, when using the image list (which I added using ImageList_AddIcon), the mask wasn't used, which resulted in blackness instead of transparency. I used ILD_TRANSPARENT when I drew the icon - which works perfectly for "unmodified" icons. The function which transformed the icon into a grayscale icon looked correct: it saved the mask, and modified each pixel using a formula similar to what you describe above. Then recreated the icon using the image bitmap and saved mask.
--
...Coca Cola, sometimes war...
|
|
|
|
|
Yes, i spent the last couple days fighting with the imagelist functions as well. I was modifying my toolbar code to accept a normal colour bitmap, apply appropriate filters, generate hot and disabled bitmaps and then generate/apply toolbar imagelists from each of the three bitmaps.
Originally i was using GDI+ Bitmap to manipulate the image (no problem) and then Bitmap::GetHBITMAP() to get a HBITMAP to pass to Imagelist_AddMasked() - no joy. The image would add but no mask would be created. No matter what i did the mask would not generate correctly.
The docs say Imagelist_AddMasked() will only work on 8bbp or less. Even when i created my own mask i couldn't get Imagelist_Add() to work. I even looked at the WINE implimentation.
I ended up writing my own code to access/manipulate the raw bitmap (24/32bbp) and pass that HBITMAP to Imagelist_AddMasked() which works. That's where i stopped. I didn't try Imagelist_AddIcon().
I found this to be infuriating !
Sorry.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
In case you ever need to draw desaturated image list images, here's a piece of code I found in WTL/atlctrlw.h:
void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point,
HBRUSH hBrushBackground = ::GetSysColorBrush(COLOR_3DFACE),
HBRUSH hBrush3DEffect = ::GetSysColorBrush(COLOR_3DHILIGHT),
HBRUSH hBrushDisabledImage = ::GetSysColorBrush(COLOR_3DSHADOW))
{
#if (_WIN32_WINNT >= 0x0501) && (_WIN32_IE >= 0x0501)
if(m_bAlphaImages)
{
IMAGELISTDRAWPARAMS ildp = { 0 };
ildp.cbSize = sizeof(IMAGELISTDRAWPARAMS);
ildp.himl = m_hImageList;
ildp.i = nImage;
ildp.hdcDst = dc;
ildp.x = point.x;
ildp.y = point.y;
ildp.cx = 0;
ildp.cy = 0;
ildp.xBitmap = 0;
ildp.yBitmap = 0;
ildp.fStyle = ILD_TRANSPARENT;
ildp.fState = ILS_SATURATE;
ildp.Frame = (DWORD)-100;
::ImageList_DrawIndirect(&ildp);
}
[snip] It doesn't work on Win2k, but then again, old style graying looks ok anyway in that chunky old GUI.
--
...Coca Cola, sometimes war...
|
|
|
|
|
About icons manipulation, there's an interesting sample in MSDN: IconPro: Icon Manager Sample[^]
And yes, the easiest way to draw icons is IMHO using an ImageList, which accepts HICON entries. Working with a mask should probably help you to do what you want.
Собой остаться дольше...
|
|
|
|
|
I've made a CEdit-derived class called CLockEdit and added a Get- and SetEnabled() function that holds the member variable to see if it should process WM_CHAR messages or not(just so the controls don't look grayed-out when disabled). So I put a CLockEdit control on a dialog that only has that control and the ok and cancel buttons. I allow the user to resize the dialog, and in turn the edit box should also resize. But any CWnd-inherited function like MoveWindow() or GetWindowRect() crashes in wincore.cpp because the hWnd of the control is null. The Methods work like they're supposed to, but I can't resize the window because it crashes on ::IsWindow() in the wincore.cpp file. Any suggestions?
[insert witty comment here]
bdiamond
|
|
|
|
|
Perhaps is your object instantiated but then not created? Do you use CWnd::SubclassDlgItem in your dialog's OnInitDialog?
Собой остаться дольше...
|
|
|
|
|
No, I'm not really familiar with SubclassDlgItem. I placed an edit box on the dialog, and associated a CEdit variable with it. Then I went and changed the type to CLockEdit instead of CEdit. The other functions I made for the derived class work, but not anything that needs an hWnd. I've read what you said and looked it up, but I can't seem to get this to work. Can you elaborate further?
[insert witty comment here]
bdiamond
|
|
|
|
|
bdiamond wrote:
Can you elaborate further?
Yes
To use your own class, there are two ways, using DDX or subclass an existing window: Here will I try to explain the second method:
Let's suppose your control as for identifier ID_MY_CONTROL. You created an edit object with this identifier with the resource editor. Next, you need to add a CLockEdit member attribute to your dialog class, let's say CLockEdit m_MyEdit. Then you have to catch the WM_INITDIALOG message, and in the corresponding method, you have to associate the CLockEdit object with the identifier: that's the role of the method CWnd::SubclassDlgItem:
m_MyEdit.SubclassDlgItem(IDC_MY_CONTROL, this);
You will find useful informations about subclassing (and certainly better explained) in this article by The Master himself: Create your own controls - the art of subclassing[^]
HTH,
K.
Собой остаться дольше...
|
|
|
|
|
I tried that before looking at the article you pointed me to and I get an ASSERTION error in this code in wincore.cpp:
ASSERT(m_hWnd == NULL);
ASSERT(FromHandlePermanent(hWndNew) == NULL);<br />
I also tried using Attach() as I saw in one of my books, and it still didn't work.
[insert witty comment here]
bdiamond
|
|
|
|
|
If you use SubclassDlgItem, be sure not to use the DDX mechanism.
Also, use SubclassDlgItem after having called the base method CDialog::OnInitDialog.
I send you a small example (using VC6), check your mail.
HTH,
K.
Собой остаться дольше...
|
|
|
|
|
That's the same thing I was doing in mine!! However, I saw that in your class the macros IMPLEMENT_DYNAMIC and DECLARE_DYNAMIC weren't there, so I removed that from mine also. Then just to be safe, I deleted the edit box, made another one and started all over. Now it works!!! I thank you a million times.
[insert witty comment here]
bdiamond
|
|
|
|
|
i'm trying to just paint to a dialog using CreateCompatibleDC(), FillRect(), etc, but i cant find the right spot to paint at, i've tried all the OnInitDialog(), etc, doesnt work, only time it works is in OnPaint() then it paints it forever and ever, help me!
|
|
|
|
|
You need to put your painting in OnPaint.
OnPaint will be called whe region needs to get repainted ( when it is Invalidated ).
If your dialog stands on top, and nothing is happening, it should not repaint itself for nothing.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
evilslope wrote:
when do i paint?
This is dependant on you geographic location. Generally it is best to paint during the driest part of the year.
-- signature under construction -- -pete
|
|
|
|
|
Papa
while (TRUE)
Papa.WillLove ( Bebe ) ;
|
|
|
|
|