Hi,

I am beginner to C++ but not to C, though I worked on C some 15 years ago.
So I need some help.

I was implementing a call to EnumEnhMetaFile () function as per the docs on
MSDN. Its prototype is:

EnumEnhMetaFile (HDC hdc, ..., CONST RECT * lpRect);

I have given only those args that are problematic. Before calling this
function, I coded as given below, taking a cue from an example on MSDN.

HDC hDc;
hDC = GetDC (hWnd);
RECT * lpRect;
GetClientRect (hWnd, lpRect);
bOK = EnumEnhMetaFile (hDc, ..., lpRect);

I get compilation errors as follows:
1. On GetDC, it says no args allowed. Also GetDC returns a "CDC *" and not
of HDC.
2. On GetClientRect, it says it takes only one arg. If I use "GetClientRect
(lpRect)", it compiles but crashes on running.

When I try to go to definitions, they point to the prototypes in "afxwin.h"
and not to that in "winuser.h".

My queries are:
1. How can I force the prototype in winuser.h rather than that in afxwin.h?
2. If that is not desirable or not possible, can I cast "CDC *" to "HDC" so
that my code will be as:

CDC * pDc;
pDC = GetDC ( );
RECT * lpRect = 0;
bOK = EnumEnhMetaFile (pDc, ..., lpRect);

3. Which is the forum for discussing GDI issues?

ThanQ...

Re: Two function prototypes in two separate .h files by Alex

Alex
Thu Dec 06 09:03:49 PST 2007

"SME" wrote:
> My queries are:
> 1. How can I force the prototype in winuser.h rather than
> that in afxwin.h?

You don't need to force it. It appears that you created MFC
project with Visual Studio rather than plain C Win32 API
project. That's why you see all these errors. MFC defines
classes for many Win32 objects (like window, DC, etc.).
Often these classes have methods with the same name as
corresponding API function. However, classes' methods expect
less parameters and other types for parameters.

When you make new project select "Win32" category instead of
MFC. Then follow the wizard to generate boilerplate code.

> 2. If that is not desirable or not possible, can I cast
> "CDC *" to "HDC" so that my code will be as:
>
> CDC * pDc;
> pDC = GetDC ( );
> RECT * lpRect = 0;
> bOK = EnumEnhMetaFile (pDc, ..., lpRect);

No, you cannot cast pointer to class to HDC and expect it to
work. Either use MFC and play by the rules or use Win32 API.

BTW, the above code will lead to access violation exception,
since there is nothing behind `lpRect' pointer. You need to
define RECT variable and pass pointer to it to the
`EnumEnhMetaFile' call:

RECT rc = { 0 };
bOK = EnumEnhMetaFile (pDc, ..., &rc);

> 3. Which is the forum for discussing GDI issues?

microsoft.public.win32.programmer.gdi
microsoft.public.platformsdk.gdi (this group seems quite
dormant)

HTH
Alex



Re: Two function prototypes in two separate .h files by Igor

Igor
Thu Dec 06 09:10:01 PST 2007

SME <smelchuri@hotmail.com> wrote:
> RECT * lpRect;
> GetClientRect (hWnd, lpRect);
> bOK = EnumEnhMetaFile (hDc, ..., lpRect);

Both GetClientRect and EnumEnhMetaFile want a RECT* pointer that
actually points to valid memory. You give them an uninitialized pointer.
Make it

RECT rect;
GetClientRect (hWnd, &rect);
bOK = EnumEnhMetaFile (hDc, ..., &rect);

> I get compilation errors as follows:
> 1. On GetDC, it says no args allowed. Also GetDC returns a "CDC *"
> and not of HDC.

There's an HDC GetDC(HWND) - a standalone WinAPI function. There's also
a member of CWnd class, CDC* GetDC() . You are calling GetDC from a
method of a class derived from CWnd, so the compiler assumes you mean
the member function, not the standalone global function. If you want the
global function, make it ::GetDC

> 2. On GetClientRect, it says it takes only one arg.

Same reason. CWnd has a member CWnd::GetClientRect which is a thin
wrapper around ::GetClientRect

> If I use
> "GetClientRect (lpRect)", it compiles but crashes on running.

That's because you give it an invalid pointer.

> 2. If that is not desirable or not possible, can I cast "CDC *" to
> "HDC"

CDC *pDC;
HDC hdc = pDC->m_hDC;

> 3. Which is the forum for discussing GDI issues?

microsoft.public.platformsdk.gdi . But none of the problems in your
post have anything to do with GDI. You are using MFC without even
apparently realising it, and without understanding it. That's the
overall problem that needs to be fixed one way or the other (either
don't use MFC, or learn it first).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: Two function prototypes in two separate .h files by Doug

Doug
Thu Dec 06 09:10:46 PST 2007

On Thu, 6 Dec 2007 11:16:45 -0500, "SME" <smelchuri@hotmail.com> wrote:

>Hi,
>
>I am beginner to C++ but not to C, though I worked on C some 15 years ago.
>So I need some help.
>
>I was implementing a call to EnumEnhMetaFile () function as per the docs on
>MSDN. Its prototype is:
>
>EnumEnhMetaFile (HDC hdc, ..., CONST RECT * lpRect);
>
>I have given only those args that are problematic. Before calling this
>function, I coded as given below, taking a cue from an example on MSDN.
>
>HDC hDc;
>hDC = GetDC (hWnd);
>RECT * lpRect;
>GetClientRect (hWnd, lpRect);
>bOK = EnumEnhMetaFile (hDc, ..., lpRect);
>
>I get compilation errors as follows:
>1. On GetDC, it says no args allowed. Also GetDC returns a "CDC *" and not
>of HDC.
>
>2. On GetClientRect, it says it takes only one arg. If I use "GetClientRect
>(lpRect)", it compiles but crashes on running.

This is because you're using MFC, your code exists inside a member function
belonging to a class derived from CWnd, and CWnd has member functions with
those names.

>When I try to go to definitions, they point to the prototypes in "afxwin.h"
>and not to that in "winuser.h".
>
>My queries are:
>1. How can I force the prototype in winuser.h rather than that in afxwin.h?

Use the scope resolution operator to make the compiler look in the global
namespace, i.e. ::GetDC and ::GetClientRect. That said, as you are writing
an MFC app, normally you should be using the MFC functions.

>2. If that is not desirable or not possible, can I cast "CDC *" to "HDC" so

No, that cast will not work. However, CDC exposes the HDC as m_hDC and also
through the function GetSafeHDC.

>that my code will be as:
>
>CDC * pDc;
>pDC = GetDC ( );
>RECT * lpRect = 0;
>bOK = EnumEnhMetaFile (pDc, ..., lpRect);

Replace pDC with pDC->GetSafeHDC(), and you should be OK. You should also
see if MFC defines the function in terms of CWnd. For that matter, would
the MFC CMetaFileDC class simplify this even further?

>3. Which is the forum for discussing GDI issues?

Probably microsoft.public.win32.programmer.gdi.

--
Doug Harrison
Visual C++ MVP

Re: Two function prototypes in two separate .h files by SME

SME
Thu Dec 06 10:41:01 PST 2007

Thanks a lot. You guys have been of great help, as usual.

Using only MFC functions and passing pDC->m_hDC, as indicated by you guys
got me through.

As I mentionend in my post, I am into C++ only recently and still goting
through those exercises. But got something in hand to deliver. Though the
issue I posted here doesn't belong to GDI, all this I am using to decode an
EMF file - that is GDI work.

It may be recalled that most of us have to do things without first learning
it. There is no time in the industry. We have to learn as we go. However the
changes in the software industry are so fast, before we master onething, it
becomes obsolete.

Thanks once again to all.

ThanQ...

"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:2oagl3dcc2g9d69h14vc9gsup0p2piqlbl@4ax.com...
> On Thu, 6 Dec 2007 11:16:45 -0500, "SME" <smelchuri@hotmail.com> wrote:
>
>>Hi,
>>
>>I am beginner to C++ but not to C, though I worked on C some 15 years ago.
>>So I need some help.
>>
>>I was implementing a call to EnumEnhMetaFile () function as per the docs
>>on
>>MSDN. Its prototype is:
>>
>>EnumEnhMetaFile (HDC hdc, ..., CONST RECT * lpRect);
>>
>>I have given only those args that are problematic. Before calling this
>>function, I coded as given below, taking a cue from an example on MSDN.
>>
>>HDC hDc;
>>hDC = GetDC (hWnd);
>>RECT * lpRect;
>>GetClientRect (hWnd, lpRect);
>>bOK = EnumEnhMetaFile (hDc, ..., lpRect);
>>
>>I get compilation errors as follows:
>>1. On GetDC, it says no args allowed. Also GetDC returns a "CDC *" and not
>>of HDC.
>>
>>2. On GetClientRect, it says it takes only one arg. If I use
>>"GetClientRect
>>(lpRect)", it compiles but crashes on running.
>
> This is because you're using MFC, your code exists inside a member
> function
> belonging to a class derived from CWnd, and CWnd has member functions with
> those names.
>
>>When I try to go to definitions, they point to the prototypes in
>>"afxwin.h"
>>and not to that in "winuser.h".
>>
>>My queries are:
>>1. How can I force the prototype in winuser.h rather than that in
>>afxwin.h?
>
> Use the scope resolution operator to make the compiler look in the global
> namespace, i.e. ::GetDC and ::GetClientRect. That said, as you are writing
> an MFC app, normally you should be using the MFC functions.
>
>>2. If that is not desirable or not possible, can I cast "CDC *" to "HDC"
>>so
>
> No, that cast will not work. However, CDC exposes the HDC as m_hDC and
> also
> through the function GetSafeHDC.
>
>>that my code will be as:
>>
>>CDC * pDc;
>>pDC = GetDC ( );
>>RECT * lpRect = 0;
>>bOK = EnumEnhMetaFile (pDc, ..., lpRect);
>
> Replace pDC with pDC->GetSafeHDC(), and you should be OK. You should also
> see if MFC defines the function in terms of CWnd. For that matter, would
> the MFC CMetaFileDC class simplify this even further?
>
>>3. Which is the forum for discussing GDI issues?
>
> Probably microsoft.public.win32.programmer.gdi.
>
> --
> Doug Harrison
> Visual C++ MVP