Archived

This topic is now archived and is closed to further replies.

byork

Gdi+ Hello World Example

Recommended Posts

I'm playing with GDI for the very time first based off some examples I found. The goal is to create a simple string that says "Hello World" on the face of my BMP image.Code (CPP) compiles fine, but the gauge crashes FSX when loaded.If I comment out the stuff in the Pre-Draw section, FSX does not crash.GDIPlus.lib was added in the linker.Any ideas?#include <Gdiplus.h> using namespace Gdiplus;GdiplusStartupInput gdiplusStartupInput;ULONG_PTR gdiplusToken; bool init = false; void FSAPI gaugecall ( PGAUGEHDR pgauge, SINT32 service_id, UINT32 extra_data ){ if(!init) { GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); init = true; } 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); SolidBrush brush(Color(255, 0, 0, 255)); FontFamily fontFamily(L"Times New Roman"); Font font(&fontFamily, 24, FontStyleRegular, UnitPixel); PointF pointF(10.0f, 20.0f); graphics.DrawString(L"Hello World!", -1, &font, pointF, &brush);}//SET_OFF_SCREEN (pelement); ***What is this for?}} break;case PANEL_SERVICE_PRE_KILL:if(init){GdiplusShutdown(gdiplusToken);init = false;} break;Any ideas?

Share this post


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

The primary culprit is probably this line....PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]->next_element[0]);If there is only one element in your gauge (ie MAKE_STATIC etc) , then there is no next_element that your gauge is tryingto reference , and that's probably why FSX is crashing.Removing the ->next_element[0] part , should resolve it.PELEMENT_STATIC_IMAGE pelement = (PELEMENT_STATIC_IMAGE)(pgauge->elements_list[0]);Regards.Ernie.

Share this post


Link to post
Share on other sites
I'm playing with GDI for the very time first based off some examples I found. The goal is to create a simple string that says "Hello World" on the face of my BMP image.
Bryan, have you looked at MS/ACES GDI+ example?http://code.msdn.microsoft.com/ESPDrawingG...?ReleaseId=1640It is very instructive because it also shows how to instantiate SimConnect as well... ;)
//SET_OFF_SCREEN (pelement); ***What is this for?
This is a macro necessary to have the gauge actually replot. If you comment it out like you have it won't draw properly... I know, it seems counterintuitive, but there you are anyway!"You force a gauge to re-plot by setting it off-screen."I've sent you a "GDI Project Template.zip" file via email that should help you get the basic structure in place for a multi-gauge project using GDI+...

Share this post


Link to post
Share on other sites
Bryan, have you looked at MS/ACES GDI+ example?http://code.msdn.microsoft.com/ESPDrawingG...?ReleaseId=1640It is very instructive because it also shows how to instantiate SimConnect as well... ;)This is a macro necessary to have the gauge actually replot. If you comment it out like you have it won't draw properly... I know, it seems counterintuitive, but there you are anyway!"You force a gauge to re-plot by setting it off-screen."I've sent you a "GDI Project Template.zip" file via email that should help you get the basic structure in place for a multi-gauge project using GDI+...
Thanks Bill and Ernie, I'll try that stuff out :-)

Share this post


Link to post
Share on other sites
I've sent you a "GDI Project Template.zip" file via email that should help you get the basic structure in place for a multi-gauge project using GDI+...
Beg, beg.... :( -Dai

Share this post


Link to post
Share on other sites
Beg, beg.... :( -Dai
Sent to ya Dai!....Note that this isn't necessarily the *best approach* to the design, but at least it provides a good entry point for building a hybrid C++/GDI+ multi-gauge cluster.For example, I'm creating Pens and Brushes in the sub-gauge code, which means they are created/destroyed at each gauge draw which is horribly inefficient!Ideally these will be created ONCE and destroyed ONCE in the main gauge as class objects.

Share this post


Link to post
Share on other sites
Sent to ya Dai!....Note that this isn't necessarily the *best approach* to the design, but at least it provides a good entry point for building a hybrid C++/GDI+ multi-gauge cluster.For example, I'm creating Pens and Brushes in the sub-gauge code, which means they are created/destroyed at each gauge draw which is horribly inefficient!Ideally these will be created ONCE and destroyed ONCE in the main gauge as class objects.
Yup Bill, those object create/destroy calls will certainly cause efficiency issues and the greater the memory footprint of the objects being created and destroyed, the worse it is.It's been a while since we last spoke. If you remember I was the 'c++ gauge dabbler' trying to get OpenGL working within FS C++ gauges, your GDI+ template (and some chats with Stasi) was a great help in my struggle to figure out the overall structure of C++ gauge code in order to get started, so thanks.If you recall, I managed to get OpenGL calls working inside Flight Simulator's gauges, but was not able to overcome the restriction of the FS gauge drawing system insisting on using a drawing surface in system memory rather than in video card memory in order to achieve full hardware acceleration...bah ;)Since then I have been getting my head around C# and XNA and one of the things that working with C#, managed code and the Garbage Collector hammers home is how important it is to not create and destroying lots of objects (especially objects that have a non-trivial memory footprint), lots and lots of times in a tight loop for instance. Budding C++ gauge programmers need to be aware of the size of the objects they are dealing with and how often the section of code the objects are being created and destroyed in is called. If they are being created inside a tight loop, then take the object's creation outside of the loop (while keeping the object still in scope of course) and reference them in the loop. Basically you are 'cacheing' them.And of course it's always good to remember that passing large objects using pointers or references is another performance trick to avoid the time cost of copying them onto the stack.Thanks for the link to the ACES GDI+ sample. I might take a look at it and take a break from C# and brush up on my C++ :)Darren

Share this post


Link to post
Share on other sites

Sorry, I posted this in the wrong forum... Please destroy it is possible.Eric

Share this post


Link to post
Share on other sites