Board index » cppbuilder » Get piece of what's Beneath the Form?

Get piece of what's Beneath the Form?


2004-05-16 12:15:04 AM
cppbuilder32
Hi all,
I need to copy piece of the background which is under my Form,
into a memory Bitmap, do some manipulations on it and then show
it on a TImage or TPaint on the form, let's say that this piece
start at location (0, 0) of the form.
So my question is how do i copy a piece of let's say 70x80
pixels which is Beneath my form into a memory Bitmap? Can i use
BitBlt to do that? this piece should look exactly as what i
will see if i will move or minimize the form and look at this
location.
If you can show me 2-5 lines of code that show how to do that
that will help very much.
Thanks for your help,
Ramy
 
 

Re:Get piece of what's Beneath the Form?

Quote
I need to copy piece of the background which is under my Form,
into a memory Bitmap, do some manipulations on it and then show
Some useful info you can find here:
www.bcbdev.com/faqs/faq37.htm
Vladimir Stefanovic
 

Re:Get piece of what's Beneath the Form?

Thanks, but that's not what i wanted, i tested the examples in
this page, and they all capture the screen WITH the form, so
instead of getting the background under the form i get image
of the form itself...
I'm looking for a way to capture what's BENEATH the Form.
Thanks,
Ramy
Quote
Some useful info you can find here:
www.bcbdev.com/faqs/faq37.htm

Vladimir Stefanovic
 

{smallsort}

Re:Get piece of what's Beneath the Form?

At 19:59:38, 15.05.2004, Ramy wrote:
Quote

Thanks, but that's not what i wanted, i tested the examples in
this page, and they all capture the screen WITH the form, so
instead of getting the background under the form i get image
of the form itself...

I'm looking for a way to capture what's BENEATH the Form.
Then hide it first. There is *no* other way to achieve what you want.
--
Rudy Velthuis (TeamB)
"Never test for an error condition you don't know how to handle."
-- Steinbach's Guideline for Systems Programmers.
 

Re:Get piece of what's Beneath the Form?

Then maybe i have to capture the image "Just before" the form
is about to be draw, but where is this place? should i capture
the image in the "OnPaint" event? i have tried it and it caused
my computer to "frozen" (i had to restart it to make it work
again). I thought that the "OnPaint" of the form is a good
place becouse it get called also when the user move the form.
Thanks.
Quote
Then hide it first. There is *no* other way to achieve what you want.
--
Rudy Velthuis (TeamB)
 

Re:Get piece of what's Beneath the Form?

Just to be more clear, this is the code that i tried to put in
the 'OnPaint' event of the form in order to get an image just
before the form is about to be draw, and as i said it caused
my PC to get "frozen", here is the code -
HDC dc = GetDC(0);
Graphics::TCanvas *ScreenCanvas = new Graphics::TCanvas;
ScreenCanvas->Handle = dc;
Image1->Picture->Bitmap->Width = Screen->Width;
Image1->Picture->Bitmap->Height= Screen->Height;
TRect rect = Rect(0,0,Screen->Width, Screen->Height);
Image1->Picture->Bitmap->Canvas->CopyRect(rect, ScreenCanvas, rect);
delete ScreenCanvas;
ReleaseDC(NULL,dc);
______
Ramy
 

Re:Get piece of what's Beneath the Form?

Ramy wrote:
Quote
Hi all,

I need to copy piece of the background which is under my Form,
into a memory Bitmap, do some manipulations on it and then show
it on a TImage or TPaint on the form, let's say that this piece
start at location (0, 0) of the form.

So my question is how do i copy a piece of let's say 70x80
pixels which is Beneath my form into a memory Bitmap? Can i use
BitBlt to do that? this piece should look exactly as what i
will see if i will move or minimize the form and look at this
location.
Consider that the display is a 2-dimensional array of pixels. Since we
don't have 3 dimensions to play with there is no such direction as
'below', therefore you can't do what you're trying to do... at least not
in the way you're trying to do it.
Something that /might/ work (although it's by no means guaranteed to do
so) is to enumerate the visible top-level windows, trim out the ones
that don't intersect the region you're trying to capture, sort them in
reverse Z-order (ie: back to front) and issue a WM_PRINT message to each
in turn.
Problem with this approach is that not all windows will necessarily
support WM_PRINT. Those that don't will ignore the message completely.
Try it and see.
Quote
If you can show me 2-5 lines of code that show how to do that
that will help very much.
No such simple solution exists.
--
Corey Murtagh
The Electric Monk
"Quidquid latine dictum sit, altum viditur!"
 

Re:Get piece of what's Beneath the Form?

And what about the following solution which i asked about before?
"Then maybe i have to capture the image "Just before" the form
is about to be draw, but where is this place? should i capture
the image in the "OnPaint" event? i have tried it and it caused
my computer to "frozen" (i had to restart it to make it work
again). I thought that the "OnPaint" of the form is a good
place becouse it get called also when the user move the form"
Thanks.
Corey Murtagh < XXXX@XXXXX.COM >wrote:
Quote

therefore you can't do what you're trying to do... at least
not in the way you're trying to do it...
 

Re:Get piece of what's Beneath the Form?

"Rudy Velthuis (TeamB)" < XXXX@XXXXX.COM >wrote:
Quote
"Never test for an error condition you don't know how to handle."
Funny - and sound advice which makes it even more funny!!
~ JD
 

Re:Get piece of what's Beneath the Form?

"Ramy" < XXXX@XXXXX.COM >wrote:
Quote
[...]
ScreenCanvas->Handle = dc;
Here you've assigned the HDC to the Handle of the canvas.
Quote
delete ScreenCanvas;
Here you delete the canvas - effectively releasing the DC.
Quote
ReleaseDC(NULL,dc);
Here you release an already released DC.
Use this instead:
ScreenCanvas->Handle = GetDC( 0 );
....
delete ScreenCanvas;
~ JD
 

Re:Get piece of what's Beneath the Form?

Ramy wrote:
Quote
And what about the following solution which i asked about before?

"Then maybe i have to capture the image "Just before" the form
is about to be draw, but where is this place? should i capture
the image in the "OnPaint" event? i have tried it and it caused
my computer to "frozen" (i had to restart it to make it work
again). I thought that the "OnPaint" of the form is a good
place becouse it get called also when the user move the form"
You misunderstand the way Windows works.
Windows doesn't paint everything 'behind' your form before it paints the
form itself. It figures out what needs to be painted based on a number
of things like Z-order, invalidated regions, etc. and just draws what's
needed. In other words, only the part of the window that is currently
visible (not obscured by other windows) will be drawn. The only time
you can be sure that the video buffer contains whatever is 'below' your
form is before the form is shown. Any other time you'll just get the
form itself.
As an example, let's say you have two windows: A and B. They are both
100 by 100 pixels in size, both in the same position on the screen
(let's say both at [0, 0]), with window A 'behind' window B. Now, let's
say Windows needs to draw the rectangular region [0, 0, 40, 40]. It
enumerates the windows which overlap that area, finds the visible
regions of both (after clipping to the update region) and sends a
WM_PAINT message (or similar) to that window. In this case, it finds A
and B, then sends a WM_PAINT to B. Window A is ignored since no part of
it is visible in the update region.
Now let's move Window B to [10, 10] and get windows to update the same
region. Windows enumerates the windows that intersect the region, which
is both A and B. The foremost is B, which accounts for only part o the
update region. In order to complete the update it needs to also draw
part of window A... they polygon region defined by the points [[0, 0],
[40, 0], [40, 10], [10, 10], [10, 40], [0, 40]]. Windows sets the
update region to this new polygon region, then fires a WM_PAINT to window A.
The important thing is that /only/ that region of Window A will make it
into the video buffer. If your program is window B, and you want to get
the remainder of window A, you won't find it in the video buffer at all.
This is /why/ copying from the video buffer (which is what you're trying
to do) will never work. The WM_PRINT message is your only real option.
It's not a /great/ option, since there's no guarantee that (or
requirement for) an arbitrary window will support it. The standard
controls /probably/ do, everything else is undefined.
That said, there's an exception. If you have a Transparent window
(under Windows XP or similar) then whatever is under the window /will/
be drawn, then the transparent window is drawn/masked over the top. I
haven't played with transparent windows as yet, so I couldn't tell you
how this is reflected in the video buffer. It's a brand new Windows
feature, so of course it won't work on older versions, and it's likely
to take a while to stabilize.
--
Corey Murtagh
The Electric Monk
"Quidquid latine dictum sit, altum viditur!"
 

Re:Get piece of what's Beneath the Form?

Thanks for the explenation, it's interesting, but it's still a
little hard for me to believe that there in no way to do
that, what i'm actually trying to do is to create part of the
form "Half-Transparent" (alpha blending) , that is, to show in
this part of the form the Logo of my company, but at the same
time to let the user see what there is Beneath the logo, like
a reflection on a glass window, for doing that i have to take
the piece of the background under the logo and combine it with
the logo, then show the result on the Form.
There must be a way to do that, and I'm trying to find it...
Ramy
Corey Murtagh < XXXX@XXXXX.COM >wrote:
Quote

You misunderstand the way Windows works.

[...]
Corey Murtagh
The Electric Monk
"Quidquid latine dictum sit, altum viditur!"
 

Re:Get piece of what's Beneath the Form?

You right, thanks! i'll check it soon and let you know.
"JD" < XXXX@XXXXX.COM >wrote:
Quote

"Ramy" < XXXX@XXXXX.COM >wrote:
>[...]
>ScreenCanvas->Handle = dc;

Here you've assigned the HDC to the Handle of the canvas.

>delete ScreenCanvas;

Here you delete the canvas - effectively releasing the DC.

>ReleaseDC(NULL,dc);

Here you release an already released DC.

Use this instead:

ScreenCanvas->Handle = GetDC( 0 );
....
delete ScreenCanvas;

~ JD
 

Re:Get piece of what's Beneath the Form?

Ramy wrote:
Quote
Thanks for the explenation, it's interesting, but it's still a
little hard for me to believe that there in no way to do
that, what i'm actually trying to do is to create part of the
form "Half-Transparent" (alpha blending) , that is, to show in
this part of the form the Logo of my company, but at the same
time to let the user see what there is Beneath the logo, like
a reflection on a glass window, for doing that i have to take
the piece of the background under the logo and combine it with
the logo, then show the result on the Form.
I thought it might be something like that.
Quote
There must be a way to do that, and I'm trying to find it...
Actually, no, there's no reason why there /must/ be a way. You're
trying to do something that Windows (prior to XP at least) doesn't support.
A number of tricks have been tried in the past to do what you're trying
to do, and in the end a lot of quite smart people have given up and gone
for the /illusion/ of transparency by capturing the screen before their
app is first drawn and using that static capture as the background. It
looks ok if you don't have anything dynamic happening behind your app,
but can be very misleading to your users.
Look into layered windows in Windows XP, which may do what you want.
But be aware that only XP (or higher?) will support them. I say /may/
do because I seem to remember that per-pixel alpha is difficult to manage.
Also have you tried issuing WM_PRINT messages to the windows under your
own? Prior to WinXP that's about your only option.
--
Corey Murtagh
The Electric Monk
"Quidquid latine dictum sit, altum viditur!"