Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gdi+ without .NET

81 views
Skip to first unread message

eu_pi...@gmx.net

unread,
Feb 4, 2009, 4:27:19 AM2/4/09
to
I´m looking for a beginners tutorial for gdi+
Google spits out 100s of hits, all related to VC++ and/or .NET, but I
couldn´t find anything for plain API.

Is there any such thing, an explanation for dummies, how to get
started with gdi+ using MinGW/GCC++?

Alf P. Steinbach

unread,
Feb 4, 2009, 4:58:14 AM2/4/09
to
* eu_pi...@gmx.net:

MingW 3.4.5 does not support GDI+, so you'd have to define things yourself.

For this, note that the basic Windows GDI+ is designed to be callable from C.

The C++ language binding is in (very Microsoft-specific!) source code form, a
header module that basically just forwards to the C API. As far as I know the
internals of that isn't documented. However, for each C API routine, or at least
most of them, it's documented roughly what the C++ language binding does.

So effectively you'd have to either use the C language binding, or define a C++
binding yourself.

Another possibility is of course to use Visual C++.


Cheers & hth.,

- Alf

Christian ASTOR

unread,
Feb 4, 2009, 5:17:11 AM2/4/09
to

Francis

unread,
Feb 4, 2009, 5:25:24 AM2/4/09
to
> MingW 3.4.5 does not support GDI+, so you'd have to define things yourself.
It is included in the Platform SDK (which can be downloaded for free).
Couldn't he simply link this into his code as well? I'm not sure how
mingw works here..

Btw, I have used gdiplus together with Visual Studio C++ Express
edition (which is free). I don't see why it couldn't be done using
another IDE.


Alf P. Steinbach

unread,
Feb 4, 2009, 6:41:09 AM2/4/09
to
* Francis:

>> MingW 3.4.5 does not support GDI+, so you'd have to define things yourself.
> It is included in the Platform SDK (which can be downloaded for free).
> Couldn't he simply link this into his code as well?

Nope. In the text that you didn't quote I explained that the C++ language
binding is in source code form. You don't link source code.


> I'm not sure how
> mingw works here..
>
> Btw, I have used gdiplus together with Visual Studio C++ Express
> edition (which is free). I don't see why it couldn't be done using
> another IDE.

I think you mean "compiler", not "IDE".

As I explained in the text that you didn't quote, the binding is Microsoft specific.


Cheers & hth.,

- Alf


PS: It's generally a good idea to read what you're replying to.

eu_pi...@gmx.net

unread,
Feb 4, 2009, 10:32:40 AM2/4/09
to

Thanks everyone for quick answers.

I know the pages at MSDN, but all I found out there, is what Alf
explained in short by "MinGW doesn´t support gdi+"

So maybe I should reword the question:
Is there an alternative to gdi+ that works in MinGW, maybe less
sophisticated?
For starters I could do with an option to handle image formats other
than *.bmp,
but for a real beginner like me it has to include an explanation for
dummies.

Alf P. Steinbach

unread,
Feb 4, 2009, 11:06:29 AM2/4/09
to
* eu_pi...@gmx.net:

> On 4 Feb., 11:17, Christian ASTOR <casto...@club-internet.fr> wrote:
>> On 4 fév, 10:27, eu_pira...@gmx.net wrote:
>>
>>> I´m looking for a beginners tutorial for gdi+
>>> Google spits out 100s of hits, all related to VC++ and/or .NET, but I
>>> couldn´t find anything for plain API.
>>> Is there any such thing, an explanation for dummies, how to get
>>> started with gdi+ using MinGW/GCC++?
>> http://msdn.microsoft.com/en-us/library/ms534077(VS.85).aspx
>> => Getting Started.
>> or GDI+ flat apishttp://msdn.microsoft.com/en-us/library/ms533969.aspx
>
> Thanks everyone for quick answers.
>
> I know the pages at MSDN, but all I found out there, is what Alf
> explained in short by "MinGW doesn´t support gdi+"
>
> So maybe I should reword the question:
> Is there an alternative to gdi+ that works in MinGW, maybe less
> sophisticated?

The old Windows GDI, of course. ;-) But it doesn't do anti-aliasing except for text.

Plus any number of graphics libraries, including the rather awkward but
apparently rich one in Boost.

For a really limited but simple library consider PNGWriter (I know about it
because it was the simplest I once could find for a tutorial).


> For starters I could do with an option to handle image formats other
> than *.bmp,

The Windows API lets you load many formats from file via OleLoadPicturePath.

But apparently (except for GDI+) it doesn't support saving. :-(

The one or two times I've tried I've not managed to make IPicture::SaveAsFile to
work, and the documentation section about saving an image just lists two shabby
C routines to help with storing as .BMP.


> but for a real beginner like me it has to include an explanation for
> dummies.

Uhm...

Sorry, this article is too short for that! :-)

eu_pi...@gmx.net

unread,
Feb 4, 2009, 1:16:29 PM2/4/09
to
On 4 Feb., 17:06, "Alf P. Steinbach" <al...@start.no> wrote:
> * eu_pira...@gmx.net:
> - Alf- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

Thank you very much,
at least I know now, where the problem is, and have a few hints to
solutions I can follow for now.

Fred

unread,
Feb 4, 2009, 2:27:44 PM2/4/09
to
<eu_pi...@gmx.net> wrote in message
news:a29b83ad-6cc2-4eda...@s9g2000prg.googlegroups.com...

>I know the pages at MSDN, but all I found out there, is what Alf
>explained in short by "MinGW doesn´t support gdi+"

Any compiler should "support gdi+".
GDIPlus is just a DLL, like any other DLL.
Just call flat apis from it, statically or dynamically.


Alf P. Steinbach

unread,
Feb 4, 2009, 4:42:34 PM2/4/09
to
* Fred:

Please make your DLL import library public.

TIA.,

- Alf

mika

unread,
Feb 5, 2009, 1:53:38 AM2/5/09
to

Yes, you can even call GDI+ apis with RAD like Delphi, as you would do
for user32.dll for example.


Alf P. Steinbach

unread,
Feb 5, 2009, 2:48:17 AM2/5/09
to
* mika:

It seems you're confusing the .NET wrapper for GDI+ with Win32 API level GDI+.

But in principle you are (by happenchance, it seems) literally right: it's no
problem to call any specific function in a DLL if you can supply the right
arguments.

However, the implied conclusion that that makes the functionality available is
false.

The functionality is available if or when you publish your g++ binding, such as
an import library or a wrapper that loads the library dynamically.

Please do.


TIA.,

- Alf

Alf P. Steinbach

unread,
Feb 5, 2009, 3:54:23 AM2/5/09
to
* Alf P. Steinbach:

Progris riport: even though I failed to build a proper import library using the
MinGW tools, which are limited, it turns out that Microsoft's Visual C++ import
library (which also is COFF format) apparently works with MinGW. :-)

However, not sure about whether it can be distributed.

Also, the necessary headers are *modified* Microsoft copyrighted code (the
original code is non-standard so it's necessary to modify it heavily in order to
compile with MinGW g++), and I don't know the legal situation wrt. that.

Anyone?

E.g. could perhaps someone at Microsoft clarify?


Cheers,

- Alf

Alf P. Steinbach

unread,
Feb 5, 2009, 7:10:55 AM2/5/09
to
* eu_pi...@gmx.net:

I've placed a MinGW g++ binding to GDI++ at

<url: http://home.no.net/alfps/cpp/mingw_gdiplus.zip>

Now I just hope Microsoft won't sue me, 'cause it's mostly their code (it's just
corrected here and there so that it compiles as standard C++).

I haven't tested this binding with Visual C++ but I doubt there are very many
snags, it "should" work with both compilers, i.e. portable stuff this.


USE:

The zip includes an import library, which you should copy to your MinGW 'lib'
folder. The import library file name is 'libgdiplus.import.a', which means that
the *library* name is 'gdiplus.import'. This is just a renamed copy of
Microsoft's import library 'GdiPlus.lib'; I found no way to create it from
scratch using MinGW tools, although someone more conversant with those tools
might do it.

You'll need to link with the import library, and also either just include
[cpp/gdiplus/gdiplus.cpp] in your build, or create a library or object code file
that you link in.

The Microsoft wrapper classes are not examples of good design: they're awkward
to use, and not entirely safe.

Example (I had to test that it worked) -- also included in the zip:

<code>
// Copyright (c) Alf P. Steinbach 2009. Use allowed under Boost licence.

#include <cpp/gdiplus/gdiplus_ms_classes.h>

#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
#include <stdexcept> // std::exception

void onPaint( HWND wnd, Graphics& gr )
{
// Draw a line.
Pen const pen( Color(255, 0, 0, 255) );
gr.DrawLine( &pen, 0, 0, 200, 100 );

// Draw some text.
SolidBrush const brush( Color(255, 0, 0, 255) );
FontFamily const fontFamily( L"Times New Roman" );
Font const font( &fontFamily, 24, FontStyleRegular, UnitPixel );
PointF const pointF( 10.0f, 20.0f );
gr.DrawString( L"Hello World!", -1, &font, pointF, &brush) ;
}

void onWmPaint( HWND wnd )
{
PAINTSTRUCT paintInfo;

HDC const dc = BeginPaint( wnd, &paintInfo );
Graphics gr( dc );

// Note: anti-aliasing must be turned on to fix GDI+ off-by-1 error in line
drawing.
gr.SetCompositingQuality( CompositingQualityHighQuality );
gr.SetInterpolationMode( InterpolationModeHighQuality ); // Can be
higher.
gr.SetSmoothingMode( SmoothingModeHighQuality ); //
Anti-aliasing.
onPaint( wnd, gr );

EndPaint( wnd, &paintInfo );
}

LRESULT CALLBACK WindowProcedure( HWND wnd, UINT message, WPARAM wParam, LPARAM
lParam )
{
switch( message )
{
case WM_DESTROY:
PostQuitMessage( EXIT_SUCCESS );
break;
case WM_PAINT:
onWmPaint( wnd );
break;
default: /* for messages that we don't deal with */
return DefWindowProc( wnd, message, wParam, lParam );
}

return 0;
}

int cppMain()
{
static wchar_t windowClassName[ ] = L"MainWindow";

WNDCLASSEX wincl; /* Data structure for the windowclass */

wincl.hInstance = GetModuleHandle( 0 );
wincl.lpszClassName = windowClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by
windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof( WNDCLASSEX );
wincl.hIcon = LoadIcon( 0, IDI_APPLICATION );
wincl.hIconSm = LoadIcon( 0, IDI_APPLICATION );
wincl.hCursor = LoadCursor( 0, IDC_ARROW );
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the
window class */
wincl.cbWndExtra = 0; /* structure or the window
instance */
wincl.hbrBackground = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );

if( !RegisterClassEx( &wincl ) ) { return EXIT_FAILURE; }

HWND const wnd = CreateWindowEx (
0, /* Extended possibilites for variation */
windowClassName, /* Classname */
L"GDI+ test using MinGW g++", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
544, /* The programs width */
375, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
GetModuleHandle( 0 ), /* Program Instance handler */
NULL /* No Window Creation data */
);

ShowWindow( wnd, SW_SHOWDEFAULT );

MSG message;
while( GetMessage( &message, NULL, 0, 0 ) > 0 )
{
TranslateMessage( &message );
DispatchMessage( &message );
}

return message.wParam; // TODO
}

int main()
{
try
{
cpp::gdiplus::Library gdiPlusLib;
return cppMain();
}
catch( std::exception const& x )
{
MessageBoxA( 0, x.what(), "Oops:", MB_ICONERROR );
return EXIT_FAILURE;
}
}
</code>

eu_pi...@gmx.net

unread,
Feb 5, 2009, 11:12:48 AM2/5/09
to
On 5 Feb., 13:10, "Alf P. Steinbach" <al...@start.no> wrote:
> * eu_pira...@gmx.net:
>

Oh wow, now THIS is great.
Only me dummy still has a problem.
I guess GdiplusStartup() and GdiplusShutdown() aren´t needed, so I
wonder, what other things are different, comapred to the explanations
on the MSDN pages?

Alf P. Steinbach

unread,
Feb 5, 2009, 6:01:20 PM2/5/09
to
* eu_pi...@gmx.net:

>
> Oh wow, now THIS is great.
> Only me dummy still has a problem.
> I guess GdiplusStartup() and GdiplusShutdown() aren´t needed, so I
> wonder, what other things are different, comapred to the explanations
> on the MSDN pages?

Mostly nothing. :-)

There's a small name change at the flat API level in one place, because they'd
used the same name for two different things and that wouldn't compile with a
standard-conforming compiler. Also, this code doesn't support DirectX. But then
I'm not sure if the original code really did, either.

At the C++ wrapper class level there's no change in how you use it (names etc.).

eu_pi...@gmx.net

unread,
Feb 5, 2009, 6:37:32 PM2/5/09
to
On 6 Feb., 00:01, "Alf P. Steinbach" <al...@start.no> wrote:
> * eu_pira...@gmx.net:
>
>
>

Thanks Alf, for all the efford, much apreciated.

0 new messages