Saving & restoring windows region in .Net, using eC++. Please help.

G

Guest

Hi everybody. We write in eC++ a .dll function to save, and another to restore a windows region. It works quite well. We did it, because it's not possible directly from .Net CF

The only problem is, it's saving the entire SCREEN not the canvas of the window passed - as a windows handle -. So, if some Window2 is over Window1, saving a region of Window1, in fact, save the whole screen. Then when restoring it show a bitmap, with Window2 overlapping Window1

Here is the code in C++, as you see quite simple. What we are doing wrong ?? .. Is possible to save a Windows regions - not the screen - ?? .. Doesnt' a device context (GetDc(hWnd)) serve to this purpose ?? .. Thank you all ! .. :-

EXPORTA HBITMAP __stdcall SaveWindowRegion(HWND hWnd, int fromX, int fromY, int toX, int toY)
HDC WindowDc, MemDc
HBITMAP hBitmap = 0;
int width, height, err = 0

if (hWnd == NULL)
err = ERR_BAD_WINDOW


if (fromX < 0 || fromY < 0 || toX < 0 || toY < 0)
err = ERR_BAD_PARAMS


if (!err)
width = toX - fromX
height = toY - fromY

WindowDc = GetDC (hWnd)
MemDc = CreateCompatibleDC (WindowDc)

hBitmap = CreateCompatibleBitmap (WindowDc, width, height)
SelectObject (MemDc, hBitmap)

if (!BitBlt (MemDc, 0, 0, width, height, WindowDc, fromX, fromY, SRCCOPY))
DeleteObject (hBitmap)
hBitmap = 0


DeleteDC (MemDc)
ReleaseDC (hWnd, WindowDc)


return hBitmap


EXPORTA int __stdcall RestoreWindowRegion(HWND hWnd, HBITMAP hBitmap, int x, int y)
HDC WindowDc, MemDc
int width, height, ret = 0

if (hWnd == NULL)
ret = ERR_BAD_WINDOW


if (hBitmap == NULL)
ret = ERR_BAD_BITMAP


if (x < 0 || y < 0)
ret = ERR_BAD_PARAMS


if (ret < 0 && ret != ERR_BAD_BITMAP)
DeleteObject (hBitmap)

} else if (!ret)
WindowDc = GetDC (hWnd)
MemDc = CreateCompatibleDC (WindowDc)
SelectObject (MemDc, hBitmap)

width = GetDeviceCaps (MemDc, HORZRES)
height = GetDeviceCaps (MemDc, VERTRES)

if (!BitBlt (WindowDc, x, y, width, height, MemDc, 0, 0, SRCCOPY))
ret = ERR_FATAL


DeleteObject (hBitmap)
DeleteDC (MemDc)
ReleaseDC (hWnd, WindowDc)


return ret
 
A

Alex Yakhnin [MVP]

Retreive the window's rectangle from its hWnd and use it in the BitBlt to
limit the window area.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

AlaSoft said:
Hi everybody. We write in eC++ a .dll function to save, and another to
restore a windows region. It works quite well. We did it, because it's not
possible directly from .Net CF.
The only problem is, it's saving the entire SCREEN not the canvas of the
window passed - as a windows handle -. So, if some Window2 is over Window1,
saving a region of Window1, in fact, save the whole screen. Then when
restoring it show a bitmap, with Window2 overlapping Window1.
Here is the code in C++, as you see quite simple. What we are doing wrong
?? .. Is possible to save a Windows regions - not the screen - ?? .. Doesnt'
a device context (GetDc(hWnd)) serve to this purpose ?? .. Thank you all !
... :)
 
G

Guest

Retreive the window's rectangle from its hWnd and use it in the BitBlt t
limit the window area

You mean using GetWindowRect(hWnd,lpRect) .. but then using it where in BitBlt.

That function, BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop) doesn't seem to accept a Rectangle as a parameter

Sorry .. I don't get yo

Robert
 
A

Alex Yakhnin [MVP]

Well... can use it :

BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdcSrc,
nXSrc, nYSrc,dwRop)


--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

AlaSoft said:
BitBlt to
limit the window area.

You mean using GetWindowRect(hWnd,lpRect) .. but then using it where in BitBlt.

That function,
BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop)
doesn't seem to accept a Rectangle as a parameter.
 
G

Guest

Well... can use it

BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdcSrc
nXSrc, nYSrc,dwRop

Yes .. but it doesn't work anyway. The problem seems to be deeper than jus using BitBlt() function .. for some reason if the Window is overlapped, then saved area is clipped or mixed

We are trying with GetDcEx, but yet without good results

Thank you

Robert


----- Alex Yakhnin [MVP] wrote: ----

Well... can use it

BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdcSrc
nXSrc, nYSrc,dwRop


-
Alex Yakhnin .NET CF MV
www.intelliprog.com | www.opennetcf.or

AlaSoft said:
BitBlt t
limit the window area
BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop
doesn't seem to accept a Rectangle as a parameter
 
A

Alex Yakhnin [MVP]

I've seen that behaviour too. It looks like the screen DC is been shared
between different windows on PPC.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

AlaSoft said:
BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdcSrc,
nXSrc, nYSrc,dwRop)

Yes .. but it doesn't work anyway. The problem seems to be deeper than jus
using BitBlt() function .. for some reason if the Window is overlapped, then
saved area is clipped or mixed.
We are trying with GetDcEx, but yet without good results.

Thank you.

Roberto


----- Alex Yakhnin [MVP] wrote: -----

Well... can use it :

BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdcSrc,
nXSrc, nYSrc,dwRop)


--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

the
BitBlt to
limit the window area.
where in
BitBlt.BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop)
doesn't seem to accept a Rectangle as a parameter.
 
G

Guest

I've seen that behaviour too. It looks like the screen DC is been share
between different windows on PPC

Thanks Alex, yes .. we are still trying with GetDcEx.

The problem is, we are writing rotated labels using a C++ function. This is alread done and works very well (see code below), but, the labels are written directly on to the Form, then we can't properly refresh the Form canvas during the OnPaint event (unless we repaint all the labels, etc). That's why we need to save it

The 'solution' to this would be if, we could write directly into the .NetCF bitmap we use to draw and redraw during the OnPaint event ( oGraphics.DrawFromImage(oMemoryBitMap))

But for this we need to get the handle of the BitMap we use to prepare the drawing (no available in .NetCF :)). And draw the rotated labels directly onto this BitMap, not the Form. Could it be possible ?? .. :-

Thanks agai

Robert

EXPORTA int __stdcall _RotaTexto (HWND hWnd, char *font, int font_size, char *label, int angle, int x, int y)
HDC hDc
LOGFONT hf
HFONT lfnt, *old_font
int ret = 0

if (hWnd == NULL)
ret = ERR_BAD_WINDOW


if (font == NULL || label == NULL || x <= 0 || y <= 0 || font_size <= 0)
ret = ERR_BAD_PARAMS


if (!ret)
hDc = GetWindowDC (hWnd)
SetBkMode (hDc, TRANSPARENT)

hf.lfHeight = font_size
hf.lfWidth = 0;
hf.lfEscapement = angle;
hf.lfOrientation = angle;
hf.lfWeight = FW_NORMAL;
hf.lfItalic = FALSE;
hf.lfUnderline = FALSE;
hf.lfStrikeOut = 0;
hf.lfCharSet = ANSI_CHARSET;
hf.lfOutPrecision = OUT_DEFAULT_PRECIS;
hf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
hf.lfQuality = DEFAULT_QUALITY;
hf.lfPitchAndFamily = 0;

memset (hf.lfFaceName, 0, LF_FACESIZE)
wcsncpy (hf.lfFaceName, (const unsigned short *) font, wcslen ((const unsigned short *) font));

lfnt = CreateFontIndirect (&hf)
old_font = (HFONT *) SelectObject (hDc, lfnt)

if (ExtTextOut (hDc, x, y, ETO_OPAQUE, NULL, (const unsigned short *) label, wcslen ((const unsigned short *) label), NULL) == 0)
ret = ERR_FATAL


SelectObject (hDc, old_font)
DeleteObject (old_font)

ReleaseDC (hWnd, hDc)
SetBkMode (hDc, OPAQUE)


return ret




----- Alex Yakhnin [MVP] wrote: ----

I've seen that behaviour too. It looks like the screen DC is been share
between different windows on PPC

-
Alex Yakhnin .NET CF MV
www.intelliprog.com | www.opennetcf.or

AlaSoft said:
hdcSrc
nXSrc, nYSrc,dwRop
using BitBlt() function .. for some reason if the Window is overlapped, the
saved area is clipped or mixed
We are trying with GetDcEx, but yet without good results
Thank you
Robert
Well... can use it
BitBlt(hdcDest, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top
hdcSrc
nXSrc, nYSrc,dwRopAlex Yakhnin .NET CF MV
www.intelliprog.com | www.opennetcf.or th
BitBlt t
limit the window area
where i
BitBltBitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop
doesn't seem to accept a Rectangle as a parameter
 
A

Alex Yakhnin [MVP]

Out of curiosity, why you couldn't d do these "rotated labels" in the
managed code?

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

AlaSoft said:
shared
between different windows on PPC.

Thanks Alex, yes .. we are still trying with GetDcEx.

The problem is, we are writing rotated labels using a C++ function. This
is alread done and works very well (see code below), but, the labels are
written directly on to the Form, then we can't properly refresh the Form
canvas during the OnPaint event (unless we repaint all the labels, etc).
That's why we need to save it.
The 'solution' to this would be if, we could write directly into the
..NetCF bitmap we use to draw and redraw during the OnPaint event (
oGraphics.DrawFromImage(oMemoryBitMap)).
But for this we need to get the handle of the BitMap we use to prepare the
drawing (no available in .NetCF :)). And draw the rotated labels directly
onto this BitMap, not the Form. Could it be possible ?? .. :)
Thanks again

Roberto


EXPORTA int __stdcall _RotaTexto (HWND hWnd, char *font, int font_size,
char *label, int angle, int x, int y) {
HDC hDc;
LOGFONT hf;
HFONT lfnt, *old_font;
int ret = 0;

if (hWnd == NULL) {
ret = ERR_BAD_WINDOW;
}

if (font == NULL || label == NULL || x <= 0 || y <= 0 || font_size <= 0) {
ret = ERR_BAD_PARAMS;
}

if (!ret) {
hDc = GetWindowDC (hWnd);
SetBkMode (hDc, TRANSPARENT);

hf.lfHeight = font_size;
hf.lfWidth = 0;
hf.lfEscapement = angle;
hf.lfOrientation = angle;
hf.lfWeight = FW_NORMAL;
hf.lfItalic = FALSE;
hf.lfUnderline = FALSE;
hf.lfStrikeOut = 0;
hf.lfCharSet = ANSI_CHARSET;
hf.lfOutPrecision = OUT_DEFAULT_PRECIS;
hf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
hf.lfQuality = DEFAULT_QUALITY;
hf.lfPitchAndFamily = 0;

memset (hf.lfFaceName, 0, LF_FACESIZE);
wcsncpy (hf.lfFaceName, (const unsigned short *) font, wcslen ((const unsigned short *) font));

lfnt = CreateFontIndirect (&hf);
old_font = (HFONT *) SelectObject (hDc, lfnt);

if (ExtTextOut (hDc, x, y, ETO_OPAQUE, NULL, (const unsigned short *)
label, wcslen ((const unsigned short *) label), NULL) == 0) {
ret = ERR_FATAL;
}

SelectObject (hDc, old_font);
DeleteObject (old_font);

ReleaseDC (hWnd, hDc);
SetBkMode (hDc, OPAQUE);
}

return ret;
}



----- Alex Yakhnin [MVP] wrote: -----

I've seen that behaviour too. It looks like the screen DC is been shared
between different windows on PPC.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

rc.bottom-rc.top,
hdcSrc,
nXSrc, nYSrc,dwRop)
than jus
using BitBlt() function .. for some reason if the Window is overlapped, then
saved area is clipped or mixed. rc.bottom-rc.top,
hdcSrc,
nXSrc, nYSrc,dwRop)
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org message
the
BitBlt to where in
BitBlt.
BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop)
doesn't seem to accept a Rectangle as a parameter.
 
G

Guest

Out of curiosity, why you couldn't d do these "rotated labels" in th
managed code

:) .. because so far we have seen this is not possible in .Net CF.

In Net 'straight' we use this

Dim graphics_path As New GraphicsPath(FillMode.Winding
Dim rotation_matrix As New Matri
Dim txtSize As Size

txtSize = mygraph.MeasureString(Eti.Texto, myFont

graphics_path.AddString(text, New FontFamily(myFont.Name), FontStyle.Regular, myFont.Size, punto, StringFormat.GenericDefault
rotation_matrix.RotateAt(-angle, New PointF(punto.X, punto.Y)
graphics_path.Transform(rotation_matrix
mygraph.FillPath(myBrush, graphics_path

This works fine under .Net. But as you can see, none of this is available in compact framework (not GraphicsPath and Matrix)

IS THERE ANOTHER WAY ?? .. please if you know tell use. Thanksss !!
 
A

Alex Yakhnin, MVP

Aha... now I understand what you meant by "rotated labels" :)
You're right this is not possible in managed code only in .NetCF.

Well if you're looking for access to the native bitmap behind the managed
Graphics take a look at Alex's article:
http://www.opennetcf.org/PermaLink.aspx?guid=fd194f13-d816-463e-ac95-a467a6293f0b
--
Alex Yakhnin, NET CF MVP
IntelliProg, Inc.
http://www.intelliprog.com
AlaSoft said:
the
managed code?

:) .. because so far we have seen this is not possible in .Net CF.

In Net 'straight' we use this:

Dim graphics_path As New GraphicsPath(FillMode.Winding)
Dim rotation_matrix As New Matrix
Dim txtSize As SizeF

txtSize = mygraph.MeasureString(Eti.Texto, myFont)

graphics_path.AddString(text, New FontFamily(myFont.Name),
FontStyle.Regular, myFont.Size, punto, StringFormat.GenericDefault)
rotation_matrix.RotateAt(-angle, New PointF(punto.X, punto.Y))
graphics_path.Transform(rotation_matrix)
mygraph.FillPath(myBrush, graphics_path)

This works fine under .Net. But as you can see, none of this is available
in compact framework (not GraphicsPath and Matrix).
 
G

Guest

Well if you're looking for access to the native bitmap behind the manage
Graphics take a look at Alex's article


Yeahp .. this is something we are going to try soon. Unfortunately I have seen many users in OpenNet telling that code doesn't work well (Alex code). We will see soon

Still, remains the GetDc/GetDcEx stuff .. why doesn't work the way we want ? .. most probably there is some concept related to Device Context we don't get well

Ohter issue is something I have read: 'use reflection to get the handle of Bitmap'

Thanks

Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top