BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Need help with GDI+

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Graphics)
View previous topic :: View next topic  
Author Message
Bruce Larrabee
Guest





PostPosted: Wed Dec 20, 2006 9:10 am    Post subject: Need help with GDI+ Reply with quote



Hello All,

//---------------------------------------------------------------------------


Ok, this code works... but the code below it does not???


//---------------------------------------------------------------------------

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

int main()
{
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

DWORD size;
HDC hdcPrint;
HANDLE printerHandle;

DOCINFO docInfo;
ZeroMemory(&docInfo, sizeof(docInfo));
docInfo.cbSize = sizeof(docInfo);
docInfo.lpszDocName = "GdiplusPrint";

// Get the length of the printer name.
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];

// Get the printer name.
if(!GetDefaultPrinter(buffer, &size))
{
printf("Failure");
}
else
{
// Get a device context for the printer.
hdcPrint = CreateDC(NULL, buffer, NULL, NULL);

// Get a printer handle.
OpenPrinter(buffer, &printerHandle, NULL);

StartDoc(hdcPrint, &docInfo);
StartPage(hdcPrint);
Graphics* graphics = new Graphics(hdcPrint, printerHandle);
Pen* pen = new Pen(Color(255, 0, 0, 0));
graphics->DrawRectangle(pen, 200, 500, 200, 150);
graphics->DrawEllipse(pen, 200, 500, 200, 150);
delete(pen);
delete(graphics);
EndPage(hdcPrint);
EndDoc(hdcPrint);

ClosePrinter(printerHandle);
DeleteDC(hdcPrint);
}

delete buffer;

GdiplusShutdown(gdiplusToken);
return 0;
}

//---------------------------------------------------------------------------


This code compiles but FAILS TO DISPLAY any graphics...


BTW, if I replace stuff like:


Gdiplus::Graphics* graphics = new Gdiplus::Graphics(hdc, NULL);


with:


using Gdiplus::Graphics;

Graphics* graphics = new Graphics(hdc, NULL);


this will also compile but also fails to dispkay any graphics??


//---------------------------------------------------------------------------

//#pragma argsused

#define UNICODE
#include <vcl.h>
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;

VOID OnPaint(HDC hdc)
{
Gdiplus::Graphics* graphics = new Gdiplus::Graphics(hdc, NULL);

Pen* pen = new Pen(Color(255, 0, 0, 255));

graphics->DrawRectangle(pen, 0, 300, 200, 150);
graphics->DrawEllipse(pen, 0, 300, 200, 150);

HatchBrush* myHatchBrush = new HatchBrush(HatchStyleCross,Color(255,0,255,0),Color(255,0,0,255));

Pen* myPen = new Pen(Color(255, 255, 0, 0), 3);

Gdiplus::Graphics mygraphics(hdc, NULL);;

mygraphics.FillRectangle(myHatchBrush, 100, 50, 100, 30);

mygraphics.DrawRectangle(myPen, 100, 50, 100, 30);

delete(myHatchBrush);
delete(myPen);

delete(pen);
delete(graphics);
}

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("GettingStarted");

RegisterClass(&wndClass);

hWnd = CreateWindow(
TEXT("GettingStarted"), // window class name
TEXT("Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters

ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

GdiplusShutdown(gdiplusToken);
return msg.wParam;
} // WinMain

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;

switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
OnPaint(hdc);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
} // WndProc

//---------------------------------------------------------------------------
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Dec 20, 2006 9:10 am    Post subject: Re: Need help with GDI+ Reply with quote



"Bruce Larrabee" <bruce_l (AT) westbrookent (DOT) com> wrote in message
news:4588a996 (AT) newsgroups (DOT) borland.com...

Quote:
Ok, this code works...

You are not doing any error checking, and there are bugs in the code anyway.
Try the following:

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>

// helper classes to manage resources automatically

class GdiPlusInit
{
private:
ULONG_PTR ultoken;
Gdiplus::Status sStatus;

public:
GdiPlusInit()
: ulToken(0)
{
Gdiplus::GdiplusStartupInput StartupInput;
sStatus = Gdiplus::GdiplusStartup(&ulToken, &StartupInput,
NULL);
if( sStatus != Gdiplus::Ok )
printf("Cannot initialize GDI+");
}

~GdiPlusInit()
{
if( ulToken != 0 )
Gdiplus::GdiplusShutdown(ulToken);
}

bool operator ! () const
{
return ( sStatus != Gdiplus::Ok );
}
};

class TDefPrinterName
{
private:
LPTSTR pData;

public:
TDefPrinterName()
: pData(NULL)
{
DWORD dwLength = 0;
if( !GetDefaultPrinter(NULL, &dwLength) )
{
printf("Cannot get length of printer name");
return;
}

if( dwLength == 0 )
return;

pData = (LPTSTR) malloc(sizeof(TCHAR) * dwLength);
if( !pData )
{
printf("Cannot allocate memory for printer name");
return;
}

memset(pData, 0, sizeof(TCHAR) * dwLength);

// Get the printer name.
GetDefaultPrinter(pData, &dwLength);

if( pData[0] == 0 )
{
free(pData);
pData = NULL;
printf("Cannot get printer name");
}
}

~TDefPrinterName()
{
free(pData);
}

bool operator ! () const
{
return ( pData == NULL );
}

operator LPTSTR ()
{
return pData;
}
};

class TPrinterJob
{
private:
bool bDocStarted;
bool bPageStarted;
HANDLE hPrinter;
HDC hDc;

public:
TPrinterJob()
: inherited(), bDocStarted(false), bPageStarted(false),
Hdc(NULL)
{
}

~TPrinterJob()
{
Close();
}

bool Open(LPTSTR Device)
{
Close();

if( !OpenPrinter(Device, &hPrinter, NULL) )
{
printf("Cannot open printer");
return false;
}

hDc = CreateDC(NULL, Device, NULL, NULL);
if( !hDc )
{
CloseHandle(hPrinter);
hPrinter = NULL;
printf("Cannot create printer context");
return false;
}

return true;
}

void Close()
{
if( bPageStarted )
{
EndPage(hDc);
bPageStarted = false;
}

if( bDocStarted )
{
EndDoc(hDc);
bDocStarted = false;
}

if( hDc )
{
DeleteDC(hDc);
hDc = NULL;
}

if( hPrinter )
{
CloseHandle(hPrinter);
hPrinter = NULL;
}
}

bool StartDoc(LPCTSTR DocName)
{
DOCINFO docInfo;
ZeroMemory(&docInfo, sizeof(docInfo));
docInfo.cbSize = sizeof(docInfo);
docInfo.lpszDocName = DocName;

if( StartDoc(hDc, &docInfo) <= 0 )
{
printf("Cannot start new document");
return false;
}

return true;
}

bool StartPage()
{
if( StartPage(hDc) <= 0 )
{
printf("Cannot start new page");
return false;
}

return true;
}

HANDLE GetPrinter()
{
return hPrinter;
}

HDC GetDC()
{
return hDc;
}
};


int main()
{
// Initialize GDI+.
GdiPlusInit gdiplus;
if( !gdiplus )
return 0;

// Get the default printer name.
TPrinterName PrinterName;
if( !PrinterName )
return 0;

// Get a printer handle.
TPrinterJob job;
if( !job.Open(PrinterName) )
return 0;

Gdiplus::Graphics graphics(job.GetDC(), job.GetPrinter());
if( graphics.GetLastStatus() != Gdiplus::Ok )
{
printf("Cannot initialize GDI+ Graphics");
return 0;
}

Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 0));
if( pen.GetLastStatus() != Gdiplus::Ok )
{
printf("Cannot initialize GDI+ Pen");
return 0;
}

if( !job.StartDoc(TEXT("GdiplusPrint")) )
return 0;

if( !job.StartPage() )
return 0;

graphics.DrawRectangle(&pen, 200, 500, 200, 150);
if( graphics.GetLastStatus() != Gdiplus::Ok )
{
printf("Cannot draw rectangle");
return 0;
}

graphics.DrawEllipse(&pen, 200, 500, 200, 150);
if( graphics.GetLastStatus() != Gdiplus::Ok )
printf("Cannot draw ellipse");

return 0;
}

Quote:
This code compiles but FAILS TO DISPLAY any graphics...

Again, you are not doing any error checking at all.

Quote:
#define UNICODE
#include <vcl.h

The VCL does not support Unicode. None of your code is using VCL classes
anyway, so you should get rid of that header altogether.

Quote:
Gdiplus::Graphics* graphics = new Gdiplus::Graphics(hdc, NULL);
snip
Gdiplus::Graphics mygraphics(hdc, NULL);;

Why are you creating two Graphics objects? You only need one.

Quote:
Pen* pen = new Pen(Color(255, 0, 0, 255));
snip
Pen* myPen = new Pen(Color(255, 255, 0, 0), 3);

Same here. You only need 1 Pen. You can change its color and width
dynamically via its SetColor() and SetWidth() methods.

Try this code instead:

#include <windows.h>
#include <gdiplus.h>

class GdiPlusInit
{
private:
ULONG_PTR ultoken;
Gdiplus::Status sStatus;

public:
GdiPlusInit()
: ulToken(0)
{
Gdiplus::GdiplusStartupInput StartupInput;
sStatus = Gdiplus::GdiplusStartup(&ulToken, &StartupInput,
NULL);
if( sStatus != Gdiplus::Ok )
MessageBox(NULL, TEXT("Cannot initialize GDI+"), TEXT("Init
error"), MB_OK);
}

~GdiPlusInit()
{
if( ulToken != 0 )
Gdiplus::GdiplusShutdown(ulToken);
}

bool operator ! () const
{
return ( sStatus != Gdiplus::Ok );
}
};


template<typename T>
void CheckStatus(const T &obj)
{
if( obj.GetLastStatus() != Gdiplus::Ok )
throw "GDI+ error";
}

void OnPaint(HDC hdc)
{
Gdiplus::Graphics graphics(hdc, NULL);
CheckStatus(graphics);

Gdiplus::Pen pen(Color(255, 0, 0, 255));
CheckStatus(pen);

graphics.DrawRectangle(&pen, 0, 300, 200, 150);
CheckStatus(graphics);

graphics.DrawEllipse(&pen, 0, 300, 200, 150);
CheckStatus(graphics);

Gdiplus::HatchBrush brush(HatchStyleCross,
Gdiplus::Color(255,0,255,0), Gdiplus::Color(255,0,0,255));
CheckStatus(brush);

pen.SetColor(Gdiplus::Color(255, 255, 0, 0));
CheckStatus(pen);

pen.SetWidth(3);
CheckStatus(pen);

graphics.FillRectangle(&brush, 100, 50, 100, 30);
CheckStatus(graphics);

graphics.DrawRectangle(&pen, 100, 50, 100, 30);
CheckStatus(graphics);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
switch( uMsg )
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
if( hdc )
{
try
{
OnPaint(hdc);
}
catch(const char *msg)
{
MessageBox(hWnd, msg, TEXT("Paint error"), MB_OK);
}

EndPaint(hWnd, &ps);
}
return 0;
}

case WM_CLOSE:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
// Initialize GDI+.
GdiPlusInit gdiplus;
if( !gdiplus )
return 0;

WNDCLASS wndClass = {0};
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndClass.lpszClassName = TEXT("clsGettingStarted");

if( !RegisterClass(&wndClass) )
{
MessageBox(NULL, TEXT("Cannot register class"), TEXT("Init
error"), MB_OK);
return 0;
}

HWND hWnd = CreateWindow(
TEXT("clsGettingStarted"),
TEXT("Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

if( !hWnd )
{
MessageBox(NULL, TEXT("Cannot create window"), TEXT("Init
error"), MB_OK);
return 0;
}

ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);

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

DestroyWnd(hWnd);
return msg.wParam;
}


Gambit
Back to top
Bruce Larrabee
Guest





PostPosted: Wed Dec 20, 2006 5:57 pm    Post subject: Re: Need help with GDI+ Reply with quote



Hello Remy,

You are right, the error handling is a very good idea.
(in spite of the fact that I'm exploring / experimenting
here). In fact not in spite of but because of.

I compiled your modifications and added a few of my own.

The code here compiles, it would be cool if you have time
to compile it yourself?

Well anyway, short of that... B)

The error after the first 'CheckStatus( graphics)'
is 'OutOfMemory', it reports 'OutOfMemory' twice??

There is no error after 'CheckStatus( pen)'. Which
seems odd...

The next error from 'CheckStatus( graphics)'
is 'InvalidParameter', after 'DrawRectangle()'
I guess that at least is no surprise...

And on beyond that in like kind...

Any help will be appreciated (if not actually remunerated).

Oh BTW it won't compile without #include <vcl.h>???

Bruce


//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#include <gdiplus.h>

//---------------------------------------------------------------------------

using namespace Gdiplus;

//---------------------------------------------------------------------------

const int smsgcount = 22;

char StatusMsgs[smsgcount][32] = {

"GenericError",
"InvalidParameter",
"OutOfMemory",
"ObjectBusy",
"InsufficientBuffer",
"NotImplemented",
"Win32Error",
"WrongState",
"Aborted",
"FileNotFound",
"ValueOverflow",
"AccessDenied",
"UnknownImageFormat",
"FontFamilyNotFound",
"FontStyleNotFound",
"NotTrueTypeFont",
"UnsupportedGdiplusVersion",
"GdiplusNotInitialized",
"PropertyNotFound",
"PropertyNotSupported",
"ProfileNotFound"
};

//---------------------------------------------------------------------------

class GdiPlusInit
{
private:

ULONG_PTR ulToken;

Gdiplus::Status sStatus;

public:

GdiPlusInit() : ulToken(0)
{
Gdiplus::GdiplusStartupInput StartupInput;

sStatus = Gdiplus::GdiplusStartup( &ulToken, &StartupInput, NULL);

if(sStatus != Gdiplus::Ok)
{
MessageBox( NULL, TEXT("Cannot initialize GDI+"), TEXT("Init error"), MB_OK);
}
else
{
MessageBox( NULL, TEXT("GDI+ Initialized..."), TEXT(""), MB_OK);
}
}

~GdiPlusInit()
{
if(ulToken != 0)
{
Gdiplus::GdiplusShutdown( ulToken);
}
}

bool operator ! () const
{
return(sStatus != Gdiplus::Ok);
}
};

//---------------------------------------------------------------------------

template<typename T>

void CheckStatus(const T &obj)
{
try
{
Status status = obj.GetLastStatus();

if(status != Gdiplus::Ok)
{
throw &StatusMsgs[status - 1][0];
}
}
catch( char *str)
{
MessageBox( NULL, TEXT( str), TEXT("Status Error!"), MB_OK);
}
}

//---------------------------------------------------------------------------

void OnPaint( HDC hdc)
{
Gdiplus::Graphics graphics( hdc, NULL);

CheckStatus( graphics);

MessageBox( NULL, TEXT( "Initialized 'graphics' object (or not)..."), TEXT( ""), MB_OK);

Gdiplus::Pen pen( Color( 255, 0, 0, 255));

CheckStatus( pen);

MessageBox( NULL, TEXT( "Initialized 'pen' object (or not)..."), TEXT( ""), MB_OK);

graphics.DrawRectangle( &pen, 0, 300, 200, 150);

CheckStatus( graphics);

MessageBox( NULL, TEXT( "Did 'DrawRectangle' (or not)..."), TEXT( ""), MB_OK);

graphics.DrawEllipse( &pen, 0, 300, 200, 150);

CheckStatus( graphics);

MessageBox( NULL, TEXT( "Did 'DrawEllipse' (or not)..."), TEXT( ""), MB_OK);

Gdiplus::HatchBrush brush( HatchStyleCross, Gdiplus::Color( 255,0,255,0), Gdiplus::Color( 255,0,0,255));

CheckStatus( brush);

MessageBox( NULL, TEXT( "Initialized 'brush' object (or not)..."), TEXT( ""), MB_OK);

pen.SetColor( Gdiplus::Color( 255, 255, 0, 0));

CheckStatus( pen);

MessageBox( NULL, TEXT( "Set color for 'pen' (or not)..."), TEXT( ""), MB_OK);

pen.SetWidth( 3);

CheckStatus( pen);

MessageBox( NULL, TEXT( "Set width for 'pen' (or not)..."), TEXT( ""), MB_OK);

graphics.FillRectangle( &brush, 100, 50, 100, 30);

CheckStatus( graphics);

MessageBox( NULL, TEXT( "Did 'FillRectangle' (or not)..."), TEXT( ""), MB_OK);

graphics.DrawRectangle( &pen, 100, 50, 100, 30);

CheckStatus( graphics);

MessageBox( NULL, TEXT( "Did 'DrawRectangle' (or not)..."), TEXT( ""), MB_OK);

return;
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_PAINT:

{
PAINTSTRUCT ps;

HDC hdc = BeginPaint( hWnd, &ps);

if(hdc)
{
try
{
OnPaint( hdc);
}
catch( const char *msg)
{
MessageBox( hWnd, msg, TEXT( "Paint error"), MB_OK);

return 0;
}

EndPaint( hWnd, &ps);

MessageBox( NULL, TEXT( "Paint loop complete..."), TEXT( ""), MB_OK);
}

return 0;
}

case WM_CLOSE:

PostQuitMessage( 0);

return 0;
}

return DefWindowProc( hWnd, uMsg, wParam, lParam);
}


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
// Initialize GDI+.

GdiPlusInit gdiplus;

if(!gdiplus)
{
return 0;
}

WNDCLASS wndClass = {0};

wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndClass.lpszClassName = TEXT("clsGettingStarted");

if(!RegisterClass( &wndClass))
{
MessageBox( NULL, TEXT( "Cannot register Window class"), TEXT( "Init error"), MB_OK);

return 0;
}

MessageBox( NULL, TEXT( "Window class registed..."), TEXT( ""), MB_OK);

HWND hWnd = CreateWindow(

TEXT( "clsGettingStarted"),
TEXT( "Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);

if(!hWnd)
{
MessageBox( NULL, TEXT( "Cannot create window"), TEXT( "Init error"), MB_OK);

return 0;
}

MessageBox( NULL, TEXT( "Window created..."), TEXT( ""), MB_OK);

ShowWindow( hWnd, iCmdShow);

UpdateWindow( hWnd);

MSG msg;

while(GetMessage( &msg, NULL, 0, 0) > 0 )
{
TranslateMessage( &msg);

DispatchMessage( &msg);
}

DestroyWindow( hWnd);

return msg.wParam;
}

//---------------------------------------------------------------------------
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Dec 21, 2006 1:52 am    Post subject: Re: Need help with GDI+ Reply with quote

"Bruce Larrabee" <bruce_l (AT) westbrookent (DOT) com> wrote in message
news:4589251d (AT) newsgroups (DOT) borland.com...

Quote:
You are right, the error handling is a very good idea.
(in spite of the fact that I'm exploring / experimenting
here). In fact not in spite of but because of.

The point I was trying to make is that because you were not doing any error
handling, the code could have been failing at any point and you would have
no way of knowing where or why. It is important to do error handling,
especially when you are first getting started with something new. You can
always take it out later when you get things working correctly.

Quote:
The error after the first 'CheckStatus( graphics)'
is 'OutOfMemory', it reports 'OutOfMemory' twice??

So you are saying that the error is coming from the creation of the Pen?

Quote:
There is no error after 'CheckStatus( pen)'. Which
seems odd...

Why does it seem odd? If the Pen is failing, then the code will never reach
the actual drawing. That is why I wrote CheckStatus() to throw an
exception.

Quote:
The next error from 'CheckStatus( graphics)'
is 'InvalidParameter', after 'DrawRectangle()'
I guess that at least is no surprise...

The code should not be reaching that point if a previous error is occuring.

Oh, I see what you did. You changed CheckStatus() to catch the exception.
Get rid of that. CheckStatus() was specifically designed to throw an
exception back to WndProc(). You are blocking that now, which means that
OnPaint() is free to happily draw whatever it wants using objects that may
be invalid.

And get rid of all the MessageBoxes in OnPaint(). Do not show a MessageBox
while drawing. OnPaint() is going to be called over and over very rapidly.
You are going to be bombarded with popup windows. You should display a
popup only when things go wrong.

Quote:
Oh BTW it won't compile without #include <vcl.h>???

There is nothing in the code that uses the VCL at all. When you created the
project, did you create it as a VCL project? Or did you use the Console
wizard and uncheck the VCL option?


Gambit
Back to top
Bruce Larrabee
Guest





PostPosted: Thu Dec 21, 2006 6:50 am    Post subject: Re: Need help with GDI+ Reply with quote

Hi Remy,

I really appreciate your taking your time to deal with this.

About the error handling. I totally got where you where coming
from about that as soon as I read it! Which made me think because
I think that generally I wouldn't have picked up on that.

I understand that the error reporting from the exception was
not placed at the right level, but it was reporting the error
which was a step in the right direction.

About the errors, I guess I wasn't clear.

Quote:

The error after the first 'CheckStatus( graphics)'
is 'OutOfMemory', it reports 'OutOfMemory' twice??

By this I meant that there where two errors reported
after:

Gdiplus::Graphics graphics(hdc, NULL);

There were no errors reported after:

Gdiplus::Pen pen(Color(255, 0, 0, 255));

What I thought was odd was that the call to
'graphics' failed but the 'pen' call did not.

You are probably correct about how I set up the
program. I used #include <vcl.h> because the linker
was complaining.

According to the docs, 'several GDI+ constructors set status
to OutOfMemory when they fail regardless of the reason for
failure'

I note that the value of OutOfMemory is 3, hardly seems like
a likely default value?


Have you got any clue why the call to 'graphics(hdc, NULL)'
is failing??


Thanks again for the help... B)


Bruce
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Dec 21, 2006 8:25 am    Post subject: Re: Need help with GDI+ Reply with quote

"Bruce Larrabee" <bruce_l (AT) westbrookent (DOT) com> wrote in message
news:4589da1a (AT) newsgroups (DOT) borland.com...

Quote:
The error after the first 'CheckStatus( graphics)'
is 'OutOfMemory', it reports 'OutOfMemory' twice??

By this I meant that there where two errors reported
after:

Gdiplus::Graphics graphics(hdc, NULL);

There couldn't have been two, as only one exception would be thrown. If you
were running inside the debugger at the time, howver, then you would see the
debugger report the exception once, and then the application's reporting of
the exception afterwards.

Quote:
According to the docs, 'several GDI+ constructors set status
to OutOfMemory when they fail regardless of the reason for
failure'

Which probably means that GDI+ is not able to use the HDC that you are
passing to it.

One thing you are not taking into account is that the wParam of the WM_PAINT
message may be passing a different HDC than BeginPaint() returns. So don't
call BeginPaint() and EndPaint() if the wParam is not zero, but instead cast
the wParam to a HDC and use it as-is.

Quote:
Have you got any clue why the call to 'graphics(hdc, NULL)'
is failing??

Probably because you are specifying a NULL device handle in the second
parameter. Get rid of that parameter altogether and just pass the HDC by
itself (the Graphics class has a separate constructor for that):

Gdiplus::Graphics graphics(hdc);


Gambit
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Graphics) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.