From: David Ching on
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
news:do6us5daj3fgusv2vvs55819r3b9grifsa(a)4ax.com...
> Note that WPF will not necessarily simplify this; if you tried the same
> techniques under
> WPF you would get the same result.

One of the benefits of WPF is that transparency/translucency is baked in.
You can actually set background brush to transparent and have it to exactly
what you think it should.

-- David

From: Lewis Z. on
On Apr 21, 10:43 am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> See below...
>
>
>
>
>
> On Wed, 21 Apr 2010 08:16:59 -0700 (PDT), "Lewis Z." <lzh...(a)gmail.com> wrote:
> >On Apr 21, 9:51 am, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> >> See below...
>
> >> On Wed, 21 Apr 2010 07:28:05 -0700 (PDT), "Lewis Z." <lzh...(a)gmail.com> wrote:
> >> >On Apr 21, 12:13 am, "David Ching" <d...(a)remove-this.dcsoft.com>
> >> >wrote:
> >> >> "Lewis Z." <lzh...(a)gmail.com> wrote in message
>
> >> >>news:2463fe87-ed85-49fd-9779-bea17da4612c(a)c36g2000yqm.googlegroups.com...
>
> >> >> > Joe, thanks for the reply. I handled the drawing of the background
> >> >> > image in the EraseBackground msg handler. After I figured out the
> >> >> > WM_DISPLAYCHANGE, I called RedrawWindow in this msg handler. It didn't
> >> >> > help all the time. Sometimes I still saw the missing image.
>
> >> >> It's perfectly fine to be drawing your image in OnEraseBkgnd(). But by
> >> >> chance did you cache the rect of the image? The rect would need to be
> >> >> recomputed when the display is changed. Also, try calling Invalidate()
> >> >> instead of RedrawWindow().
>
> >> >No, I don't. Neither I know how to do the caching. I tried
> >> >Invalidate() in OnDisplaySettingChanged(), and I didn't see any
> >> >changes.
>
> >> >> > I have basic OnPaint function, meaning it just calling
> >> >> > CDialog:OnPaint(). I commented out my OnPaint function. Now the
> >> >> > background image is diaplayed all the time whenever the display
> >> >> > setting is changed. But new problem shows up. Calling SetDlgItemText()
> >> >> > is causing problems. It shows some garbled texts unless screen is
> >> >> > refreshed. (I have a timer periodically displaying texts with null
> >> >> > brush to show transparent texts.)
>
> >> >> Oh if you're using transparent brushes, all bets are off, since there is no
> >> >> way to erase the current contents when the area needs to be repainted from
> >> >> scratch. The way to start from scratch is to do ShowWindow(SW_HIDE);
> >> >> followed by ShowWindow(SW_SHOW) on the offending dialog controls.
>
> >> >For the string display, I want to make them transparent and also no-
> >> >flicker. Right now I set an blank string first and then set the string
> >> >I want to display. It seems to solve the issue. But I still see
> >> >garbled texts intermittently.
>
> >> ****
> >> In general, you should not be using SetDlgItemText, but instead creating control member
> >> variables and calling SetWindowText on those variables.
>
> >Sorry I'm not aware of the difference. Could you please elaborate a
> >little?
>
> ****
> Functionally, there is no difference; from an aesthetic viewpoint, having control
> variables is more consistent with MFC style (SetDlgItemText is "so Petzold", and one of
> the first things you need to learn in programming MFC is that nearly everything in
> Petzold's book is stylistically incompatible with MFC [and, IMNSHO, with good programming
> style in general; it took me two years to overcome the bad training I got from his book])
>                                 joe
> ****
>
> >> Also, you did not say if these are edit controls or static controls; you just said "string
> >> display" which is not meaningful. Edit controls do not support SetBkMode(TRANSPARENT). I
> >> have not done this with static controls so I can't suggest what has gone wrong, but there
> >> are numerous internal bugs in these controls (for example: Microsoft, instead of doing an
> >> Invalidate() and letting WM_PAINT be sent, internally "optimizes" the behavior by directly
> >> calling the text-drawing subroutine, which is a colossally stupid move, since it presumes
> >> that the OnPaint has not been overridden. But this is what you expect when you put
> >> critical software decisions in the hands of beginners without adult supervision.
> >> joe
> >> ****
>
> >Yes, I do use static controls for transparent effect.
> >SetBkMode(TRANSPARENT) is handled in OnCtlColor().
>
> ****
> Note that this will not erase what is already there!  So if you want to replace the text,
> you must draw the background in OnEraseBkgnd, or completely redraw it in OnPaint.

Based on my spy++ logs, there seems to be some timing issue. If
OnPaint() happens before OnEraseBkgnd(), the dialog looks fine.
Otherwise, the image is missing because I redraw the image in
OnEraseBkgnd() and OnPaint() is just calling CDialog::OnPaint().

> Transparent means "do not replace any pixels that are not covered by actual parts of a
> character glyph", so if you had ###" and want to now draw "III' you will see something
> like
> *##
> where the * represents the splodge of the III drawn on top of (but not replacing) the #.
> And you can't use this technique to let a background of the parent window show through;
> you have to invalidate the area of the parent, e.g.,
>
>         CRect r;
>         GetWindowRect(&r);
>         CWnd * parent = GetParent();
>         parent->ScreenToClient(&r);
>         parent->Invalidate(&r);
>
> to force the parent area to redraw under the control.

I have this in my code except I Invalidate the static controls instead
of the whole dialog box. Otherwise the screen is blinking everytime
the texts are updating.


Joe & David, thank you for the replies.

>
> Be careful what you ask for, you may get it.  The behavior you are seeing with transparent
> mode is EXACTLY what is SUPPOSED to happen!
>
> Note that WPF will not necessarily simplify this; if you tried the same techniques under
> WPF you would get the same result.
>                                         joe
>
>
>
> >I hope this will be my last MFC project. I'm thinking to move to WPF.
>
> >> >> -- David
>
> >> >Thank you.
>
> >> Joseph M. Newcomer [MVP]
> >> email: newco...(a)flounder.com
> >> Web:http://www.flounder.com
> >> MVP Tips:http://www.flounder.com/mvp_tips.htm-Hide quoted text -
>
> >> - Show quoted text -
>
> Joseph M. Newcomer [MVP]
> email: newco...(a)flounder.com
> Web:http://www.flounder.com
> MVP Tips:http://www.flounder.com/mvp_tips.htm- Hide quoted text -
>
> - Show quoted text -

From: David Ching on
"Lewis Z." <lzhou8(a)gmail.com> wrote in message
news:f11ffc9b-d2af-43db-be64-aeb4d2732f10(a)c21g2000yqk.googlegroups.com...
>> CRect r;
>> GetWindowRect(&r);
>> CWnd * parent = GetParent();
>> parent->ScreenToClient(&r);
>> parent->Invalidate(&r);
>>
>> to force the parent area to redraw under the control.
>
> I have this in my code except I Invalidate the static controls instead
> of the whole dialog box. Otherwise the screen is blinking everytime
> the texts are updating.
>

Instead of doing Invalidate(), do a ShowWindow(SW_HIDE); followed by
ShowWindow(SW_SHOW);
Invalidating doesn't work because your transparent brush won't erase the
current contents, so if the new contents don't match exactly, it will appear
garbage. I notice a funny effect with ClearType enabled that the new
contents don't exactly match the old contents even though the string is the
same (it looks like the text is shifted by a subpixel or two).

-- David

From: Lewis Z. on
On Apr 21, 12:55 pm, "David Ching" <d...(a)remove-this.dcsoft.com>
wrote:
> "Lewis Z." <lzh...(a)gmail.com> wrote in message
>
> news:f11ffc9b-d2af-43db-be64-aeb4d2732f10(a)c21g2000yqk.googlegroups.com...
>
> >>         CRect r;
> >>         GetWindowRect(&r);
> >>         CWnd * parent = GetParent();
> >>         parent->ScreenToClient(&r);
> >>         parent->Invalidate(&r);
>
> >> to force the parent area to redraw under the control.
>
> > I have this in my code except I Invalidate the static controls instead
> > of the whole dialog box. Otherwise the screen is blinking everytime
> > the texts are updating.
>
> Instead of doing Invalidate(), do a ShowWindow(SW_HIDE); followed by
> ShowWindow(SW_SHOW);
> Invalidating doesn't work because your transparent brush won't erase the
> current contents, so if the new contents don't match exactly, it will appear
> garbage.  I notice a funny effect with ClearType enabled that the new
> contents don't exactly match the old contents even though the string is the
> same (it looks like the text is shifted by a subpixel or two).
>
> -- David

HI David,

Are you suggesting something like this,

SetDlgItemText(staticId, pTxt);
ShowWindow(SW_HIDE);
ShowWindow(SW_SHOW);

If so, this doesn't work for me. The reason is that Hide/Show causes
the window blinking all the time because I have timer running in the
background to update the texts. Although this will remove all garbled
texts, I cannot use it and user won't be happy either.

Sorry I have used SetDlgItemText() again.

Louis
From: David Ching on
"Lewis Z." <lzhou8(a)gmail.com> wrote in message
news:f249de46-a08f-4c8e-b1ad-3a9728494b86(a)z7g2000yqb.googlegroups.com...
> Are you suggesting something like this,
>
> SetDlgItemText(staticId, pTxt);
> ShowWindow(SW_HIDE);
> ShowWindow(SW_SHOW);
>
> If so, this doesn't work for me. The reason is that Hide/Show causes
> the window blinking all the time because I have timer running in the
> background to update the texts. Although this will remove all garbled
> texts, I cannot use it and user won't be happy either.
>

No, I am suggesting something like:

GetDlgItem(staticId)->ShowWindow(SW_HIDE);
GetDlgItem(staticId)->ShowWindow(SW_SHOW);

-- David