|
I have the same problem.
We should do the background copy right after the show of parent window and before the show our control.
But where is it?
Hawk
|
|
|
|
|
Hi !
Has anybody managed to realize a Transparent Radio Button (based on CButton or special class)?.
All solutions I found, tested etc. always do not seem to care about what is written in OnEraseBkgnd... and always display an annoying block underneath the control. Very nasty when trying to put the control upon a picture.
I would appreciate any help !
On the other hand: Very good work this TransparentStatic !!!!
Best regards, Norbert
|
|
|
|
|
|
thanks your good example first,
but I could not figure out why
bitmp static or mystatic/mystatic2 can show up?
since the bitmp static and mystatic/mystatic2 overlaped each other.
so i could not understand why in OnSetText() procedure, the parent can show the bitmap .
would you give some details on this?
thanks much.
nothing nothing nothing
|
|
|
|
|
If I understand correctly, you are asking how does the system know to draw the two static text control on top of the static bitmap control.
That has to do with the ZOrder of the controls. The controls with higher ZOrder will show up on top of controls with a lower ZOrder.
This can be set in the dialog editor by setting the tab order of the controls. And you can also set this programatically using SetWindowPos, the first parameter is used to change the ZOrder of a window.
Ali
|
|
|
|
|
AliRafiee wrote:
That has to do with the ZOrder of the controls. The controls with higher ZOrder will show up on top of controls with a lower ZOrder.
after a few try, I think so, but I have not gotten the inferior from the tries.
1)
I new a project with two statics, one Labled "aaaa",
another one labled "bbbbbbbbbbbbbbbbb",
and the "aaaa" is bigger than "bbbbbbbbbbbbbbbbbbbbb" in size.
2)
in the resource file,
i changed the occurence of the two static to change their Zorders.
also I have test the WS_EX_TRANSPARENT.
the test cases and the corresponding results are:
a)
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0
result:only "aaaa" is visible.
i think this is normal because aaaa is larger than bbbbbbbbbbbb, and aaaa is on top of bbbbbbbbbbb.
b)
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,
WS_EX_TRANSPARENT
LTEXT "aaaa",IDC_STATIC,31,15,123,67
result: both are visible;
why??? MSDN states if a window with WS_EX_TRANSPARENT set,windows below it at the position where the original window was initially placed are not obscured and show through.
c)
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,
WS_EX_TRANSPARENT
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0,WS_EX_TRANSPARENT
result: same as a) case, only "aaaa" is visible
why????
d)
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0,WS_EX_TRANSPARENT
result: same as a) case, only "aaaa" visible
why???
e)
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0,WS_EX_TRANSPARENT
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20
result: only "aaaa" is visible
why????
f)
LTEXT "aaaa",IDC_STATIC,31,15,123,67
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20
result:both "aaaa" and "bbbbbbbbbbbbbbbbbbbb" is visible.
this case i see why, because bbb is smaller than aaaa, and the Zorder is bbbb above aaaa.
g)
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0,WS_EX_TRANSPARENT
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,WS_EX_TRANSPARENT
result: both visible.
h)
LTEXT "aaaa",IDC_STATIC,31,15,123,67
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,WS_EX_TRANSPARENT
result: both visible
in e,f,g,h I will think both static should be visible because bbbbb is above "aaaa" no matter whether WS_EX_TRANSPARENT is set with or not. but case e) defeated me.
would you be kind to give me more details? thanks
|
|
|
|
|
Try this. And get rid of those WS_EX_TRANSPARENTS
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,
Like I said in the last message. The control with the higher ZOrder will show up on top of the other controls.
In the above code "aaaa" has a lower zorder than "bbbbbbb" so bbbb will show up on top of aaaaaa
in your example
LTEXT "bbbbbbbbbbbbbbbbbbbbbbb",IDC_STATIC,42,41,98,20,0,
LTEXT "aaaa",IDC_STATIC,31,15,123,67,0
aaaa has a higher zorder
Keep in mind that if you want to change the text for the larger static control ("aaaaaaaa"), then you will need to reset the text for the smaller ("bbbbbbbbbbb") one also
Ali
|
|
|
|
|
Hi,
You mentioned a possible forthcoming Transparent ListBox. Just wondering if it exists?
Thanks,
-Vin
|
|
|
|
|
Hi Vin,
I have the Transparent List box, but I have been so busy at work that I haven't been able to finilize it (and clean up) so that I can post it. If you like I can email you what I have. It might be a good starting point.
AliR
|
|
|
|
|
I emailed you the code to the email you have me and it bounced back, I improvised a couple of time, but then all bounced back. If you don't get the code, then send me another email.
I should have the code posted here at codeproject by next week.
|
|
|
|
|
The problem with the static method though, is that when the window becomes visible, if there is an always on top window in front of it, then you copy part of that window instead and that becomes your background when you do subsequent erasures.
|
|
|
|
|
Thanks for point that out. I am assuming that you are talking about method 1.
Using method 2 should eliminate that problem for you.
And if method 2 is not what you want, then you can simple make your window top most for an instant while the window get's drawn for the first time and then restore the zorder back to not top most.
For example: (If you are using it in a dialog box)
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//set the window to topmost
SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
//set a timer to be called immediately after the window is drawn
SetTimer(100,0,NULL);
return TRUE;
}
void CMyDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent == 100)
{
KillTimer(nIDEvent);
SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
}
CDialog::OnTimer(nIDEvent);
}
It might seem a bit awkward, but there is always a price to pay to get the cool things in windows.
AliR
|
|
|
|
|
Your method will still not work if it is being obscured by a topmost window, because setting windows position to wndTopMost will only set is above all non-topmost windows. Any topmost windows that previously existed will still obscure your window.
Here's a better solution (this is how I've implemented it in my button class). I have two methods in OnEraseBkgnd() based on a BOOL flag -- default is to use CDC::GetPixel() to identify solid color backgrounds. To use the control over an image background they must call a button method SetImageBg(TRUE, IMAGE_RESOURCE_ID) , which sets the boolean erasure flag (BOOL bImageBg ) to true and stores the image resource ID in a member variable (UINT m_background ). From there this is how I've implemented the solution in OnEraseBkgnd() :
if(bImageBg && m_background != 0)
{
if (m_Bmp.GetSafeHandle() == NULL)
{
m_Bmp.LoadBitmap(m_background);
CRect Rect;
GetClientRect(Rect);
this->ScreenToClient(&Rect);
CPoint pt = Rect.TopLeft();
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);
pDC->BitBlt(pt.x,pt.y,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBmp);
m_Bmp.DeleteObject();
}
}
This method is a little more "memory efficient" because it doesn't store a bitmap in memory for each control instance, it only stores a resource identifier (UINT). The bitmap is loaded and painted and then immediately deleted. It's probably not an issue anyway... but feel free to modify this to your own liking. At least it's a method that works and will get you pointed in the right direction.
In business, if two people always agree, one of them is unnecessary.
-- modified at 2:13 Tuesday 7th March, 2006
|
|
|
|
|
Hi,
first thanks for your smart control.
I'm using VC6 and I have the following problem:
My CStatic controls are created by directly calling the CStatic::Create() method. So I guess the ON_WM_CTLCOLOR_REFLECT() message isn't initialized correctly, because the CtlColor() method is never called. If I create the control via the MFC framework (resource editor) everything works fine.
Do you have any idea how to fix this problem?
Thanks a lot.
Ralph
|
|
|
|
|
I wasn't able to recreate your problem.
I am emailing you an example of both controls begin created dynamically. If you don't get the email, feel free to contact me again.
Ali Rafiee
|
|
|
|
|
I am having the same problem -- any chance you can post up a copy of the dynamically created version? For what its worth here is my code:
m_TestText.Create( _T( "test text" ), WS_CHILD | WS_VISIBLE, CRect( 0, 0, 100, 100 ), this, 123 );
Thanks
Casey
|
|
|
|
|
|
Hello
The first photo in the article, in my Firefox loads from bottom to top, which is curious for me, and with the internet explorer doesn't load !!!
Do you know what happens??
Thanks, and sorry for the offtopic
|
|
|
|
|
It's a Progressive JPEG. Sometimes they get drawn funny like that. I don't know why, but I've seen it in the past on browsers that support progressively painting jpegs.
A PJPEG is formatted such that it can be painted as data becomes available (as more bytes are downloaded.)
|
|
|
|
|
Are these methods able to handle shadow in alpha channels (32bit bitmaps) or do they have to be changed for that?
|
|
|
|
|
These classes simply define how to do simple transparency. If you use CTransparentStatic2 you should be able to easily incorporate alpha blending of the background using GDI+, in the "else" part of OnEraseBkgnd Method.
|
|
|
|
|
Is there any MFC 7 function in your sample that would not make it work for VC6?
William
Fortes in fide et opere!
|
|
|
|
|
The sample application was done using Visual C++ .Net 2002. There might be something in stdafx.h that VC6 might not like.
Anyway, I have included a Visual C++ 6.0 project in the sample (TransStaticSample6)
Ali
|
|
|
|
|