Sign in to follow this  
n4gix

Setting up GDI+, help please!

Recommended Posts

can anybody give me an example of what steps need to be followed for MS VC++ to allow gdiplus.h to be included? I get compile errors complaining about elements in gdiplus.h (first error is on a line that says "namespace Gdiplus", even though I have included windows.h before it. Are there other includes that are required besides these two? My gauge works and compiles fine, but I'm now starting to look into using GDI+ for some of the drawing, and I can't get past this most simple step!

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

Can you post some code?Just including windows.h and Gdiplus.h should be fine so maybe you are doing something wrong that seeing some code would show.

Share this post


Link to post
Share on other sites

Thanks for the reply. I can certainly post some code, but I believe my issue is far more fundamental than that. Let me elaborate on what I'm trying to do, and then if you think code is still necessary, I'll have to figure out what code you want to see since this issue is with the microsoft gdiplus.h header file and how it interacts with the compiler.My gauge started from the examples from sd2gauxx.zip, the code is not complicated (but the artwork sure is!) I simply wanted to add some more robust text on the gauge that the MAKE_STRING macro didn't seem to support. Specifically, the MAKE_STRING macro seems to always put text on the gauge using equidistant spacing between characters, even though the font is Arial, a non-proportional font. Furthermore, I need to make the positioning of the text dynamic, and the macro won't compile with a variable in the Y-coordinate, it wants that position to be a constant. In my reading, it apperas I need to get away from the MAKE_STRING macro in order to take more control of the text formatting, which is what led me to GDI+, but of course, that has opened up a whole new can of worms.See the attached image, I have pointed out the text that needs to move dynamically with the vertical speed indicator, but MAKE_STRING wont' let me move it because it won't let me use a variable for the Y-coordinate. Also notice that the text (numbers) 29.92 in the barometric pressure window are using equidistant spacing, not the spacing appropriate for the font.So if GDI+ is not necessary to accomplish my needs, then perhaps I'm going down the wrong road anyway. But if GDI+ is what I need in order to make the text do what I want, then I need to figure out what the C++ environment needs to look like to accomodate that.

Share this post


Link to post
Share on other sites

First, the name of the gauge's code file should use the .cpp extension.Next, you will need to set up the header of the gauge code something like this:// Set up gauge header// This is public domain, a help tool for developers to understand how// To set up a gauge, and set it up with GDI+// Version 1.0#include char pfd_gauge_name[] = GAUGE_NAME;extern PELEMENT_HEADER pfd_list;extern MOUSERECT pfd_rect[];GAUGE_CALLBACK PFDCallBack;bool init = false;using namespace Gdiplus;GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken;int brt=100;GAUGE_HEADER_FS700(GAUGE_W, pfd_gauge_name, &pfd_list, pfd_rect, PFDCallBack, 0, 0, 0);You will need to sandwich in a drawing surface just above your background MAKE_STATIC:#define MAP_LEFT_BORDER 20 //set these to the top left corner of the #define MAP_TOP_BORDER 10 //drawing surface!MAKE_STATIC( pfd_image, BMP_DRAWING_SURF, NULL, NULL, IMAGE_USE_ERASE|IMAGE_USE_BRIGHT|IMAGE_CREATE_DIBSECTION, 0, MAP_LEFT_BORDER,MAP_TOP_BORDER)PELEMENT_HEADER pfd_next[] = { &pfd_image.header, NULL };Next, you will need code to start GDI+:void FSAPI PFDCallBack ( PGAUGEHDR pgauge, SINT32 service_id, UINT32 extra_data ){ if(!init) { GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); init = true; }Then, continue with the drawing code in PANEL_SERVICE_PRE_DRAW: switch (service_id) { case PANEL_SERVICE_PRE_DRAW: { PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]->next_element[0]); if (pelement) { HDC hdc = pelement->hdc; PIXPOINT dim = pelement->image_data.final->dim; if (hdc) { Graphics graphics(hdc); graphics.SetTextRenderingHint(TextRenderingHintAntiAlias); Pen whitePenthick(Color(255, (255*brt)/100, (255*brt)/100, (255*brt)/100), 0.01*dim.y); Pen whitePenmedium(Color(255, (255*brt)/100, (255*brt)/100, (255*brt)/100), 0.006*dim.y); Pen whitePen(Color(255, (255*brt)/100, (255*brt)/100, (255*brt)/100), 0.002*dim.y); Pen bluePen(Color(255, (39*brt)/100, (25*brt)/100, (99*brt)/100), 0.01*dim.y); Pen greenPen(Color(255, (93*brt)/100, (188*brt)/100, (90*brt)/100), 0.006*dim.y); Pen yellowPen(Color(255, (254*brt)/100, (238*brt)/100, 0), 0.006*dim.y); Pen redPen(Color(255, (237*brt)/100, (38*brt)/100, (41*brt)/100), 0.006*dim.y); REAL dashValues[2] = {0.01*dim.y, 0.005*dim.y}; Pen whitePendash(Color(255, (255*brt)/100, (255*brt)/100, (255*brt)/100), 1); whitePendash.SetDashPattern(dashValues, 2); SolidBrush blackBrush(Color(255, 0, 0, 0)); SolidBrush greenBrush(Color(255, (93*brt)/100, (188*brt)/100, (90*brt)/100)); SolidBrush whiteBrush(Color(255, (255*brt)/100, (255*brt)/100, (255*brt)/100)); FontFamily Arial(L"Arial"); Font TempTitles(&Arial, 0.085*dim.y, FontStyleBold, UnitPixel); PointF pointF(0.158*dim.x, 0.176*dim.y); graphics.DrawString(L"MKR", -1, &TempTitles, pointF, &whiteBrush); PointF pointF1(0.15*dim.x, 0.245*dim.y); graphics.DrawString(L"MUTE", -1, &TempTitles, pointF1, &whiteBrush); } SET_OFF_SCREEN (pelement); } } break;Then, don't forget to shut down GDI+... :) case PANEL_SERVICE_PRE_KILL: if(init) { GdiplusShutdown(gdiplusToken); init = false; } break; }}/////////////////////////////////////////////////////////////////////////////#undef MAP_LEFT_BORDER#undef MAP_TOP_BORDER#undef GAUGE_NAME#undef GAUGEHDR_VAR_NAME#undef GAUGE_W

Share this post


Link to post
Share on other sites

I'll try changing the extension to cpp, but remember, it's .c because it's straight C, not C++. Perhaps I'm missing something really silly here, but let me attempt to clarify. When my compiler is set to compile straight C code, without any "#include gdiplus.h", it compiles my gauge successfully. But when I add the lines: #include "windows.h" #include "gdiplus.h" into my gauge's .c file, and added absolutely no other gdiplus code, the compiler chokes because it doesn't like things that are in the gdiplus.h HEADER. The compiler error is: gdiplus.h(25) : error C2061: syntax error : identifier 'Gdiplus' Then I read someplace that "namespace" (the keyword on the flagged line in the header) is only available in C++, so I tried changing the compiler switches to C++ instead of straight C, and then I get a different compiler error in gauges.h (a header we shoudn't need to change right?). The new error when compiling under C++ is: gauges.h(4590) : error C4430 : missing type specifier - int assumed. Note: C++ does not support default-int. Even excluding the gdiplus part of this question, my working gauge won't compile if I switch the compiler to /TP (compile as C++). So there's my catch-22: 1. Do I need to use C++ in order to use gdiplus? 2. If yes, then why is gauges.h choking when compiled as C++ instead of C.

Share this post


Link to post
Share on other sites

POSSIBLE SOLUTION:The line in GAUGES.H that fails when included in a C++ program is:typedef (*GAUGE_KEY_EVENT_HANDLER) (ID32 event, UINT32 evdata, PVOID userdata);On a whim, I have modifed the above line in GAUGES.H header, adding 'int' after the typedef keyword: typedef int(*GAUGE_KEY_EVENT_HANDLER) (ID32 event, UINT32 evdata, PVOID userdata);And the compile works, and so far it appears that the gauge works. I am using Visual Studio 2005, v8.0.50215.44 beta 2. I wonder if the gauges.h syntax is no longer supported in the newer compiler, or if this is a bug in the compiler?

Share this post


Link to post
Share on other sites

LOL! We're "talking" on two different forums...As I said in freeflightdesign.com though, you are using a "stock" gauges.h file...I'll send you a modified fs9gauges.h that will actually work... ;)

Share this post


Link to post
Share on other sites

HA!!!! I worried about posting that question to 2 forums for that exact reason!I was able to successfully walk the plist to find the desired 'sandwiched' drawing layer as we discussed. However, is there an approach to making that drawing layer "transparent"? I have read that we can't use IMAGE_USE_TRANSPARENCY on that layer, which makes sense, so I'm assuming I need to somehow capture the layers "as drawn" up to the point of the sandwich layer and then 'paint' that captured region as the initial background of my drawing layer. I'm just not sure how to go about capturing the underlying region like that. Is there is common method to accomplish this?

Share this post


Link to post
Share on other sites

Why you you need it to be transparent? Are you building a HUD? If so, then I don't know how to accomplish such a goal. I know it is possible, 'cause others have done it, but they haven't shared their knowledge with the rest of us dummies... ;)If not building a HUD, then I don't see any need for the hdc surface to be "transparent..." If it is the next-to-last-layer of the 'sandwich,' then there isn't anything under it...OTOH, there's nothing that says you must use a 'blank, monochromatic canvas' for your drawing surface! You can use any image you want for the hdc surface's bitmap...

Share this post


Link to post
Share on other sites

I started a new thread on this transparency issue, with a description of why. Thread titled: "C++ Guage - Copying "stacked" layers"Specifically, it's the G1000's vertical speed indicator.....see other thread for a link to a picture.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this