Page 1 of 1

Wide Character String conversion strangeness

Posted: Sun May 21, 2006 2:26 pm
by Xharock
I have made a dialog box in which the user can enter the path and name of the heightmap file they wish to open which will then be used to generate a terrain. Of course the text from the editbox is a wide character string whereas the parameter for addTerrainSceneNode needs a const char *. I thought I had converted them OK as I got no errors when compiling. I did it like this:

Code: Select all

WHeightmap = FName;
strcpy(Heightmap, stringc(WHeightmap).c_str());

CreateBase(Heightmap, Colourmap, Detailmap);
Where WHeightmap is the Wide character string and FName is the data from the editbox. (Heightmap, Colourmap, Detailmap) are char arrays with [256] "spaces". However once I've entered the path and the name and click OK I get this in the console:

Image

Whats even more strange is that if I leave the value in the editbox as it's default (Which is MyMedia.AMP) it will still say it cannot find the file (Because it doesn't exist) but the filename doesn't appear as weird symbols. Can anyone help me?

Posted: Sun May 21, 2006 7:16 pm
by Xharock
Yeah this is really annoying I can't load anything from input from an editbox... which is kinda crucial to my project.

Posted: Sun May 21, 2006 11:12 pm
by vitek
I'm pretty sure you are doing something wrong. The following code works just fine...

Code: Select all

class MyEventReceiver : public IEventReceiver
{
public:
   MyEventReceiver()
   {
   }

   virtual bool OnEvent(SEvent event)
   {
      if (event.EventType == irr::EET_GUI_EVENT && event.GUIEvent.EventType == EGET_EDITBOX_ENTER)
      {
         fprintf(stderr, "%s\n", core::stringc(event.GUIEvent.Caller->getText()).c_str());
         return true;
      }

      return false;
   }
};
Also, it is probably a good idea to avoid using fixed length buffers for strings. It is easy for users to overflow your buffers which can cause the program to crash. The value returned from IGUIElement:getText() is a string of arbitrary length. Just store it as a core::stringw or core::stringc and pass that around.

If you absolutely must use fixed length buffers, make sure to write code that guards against overflows.

Travis

Posted: Mon May 22, 2006 6:36 am
by Xharock
Didn't work. Still gives me a load of gobbledeegook. I am having to put two strings together in order to get the full path and file name. The user inputs them separatly and my program i suposed to put them together and use the file to create a heightmap. I changed the character arrays to stringc's by the way.

Posted: Mon May 22, 2006 7:21 am
by vitek
What didn't work? Was the value printed by the fprintf call all goobered up? It might also be important to know what platform/compiler you are using.

It might be in your best interest to write a short test case to illustrate the problem and post the code here. I am still not convinced that you are not shooting yourself in the foot. Maybe you could just provide a bit more of your code so we can find what is going on.

Here is a complete testcase that shows the edit control does work, at least on my machine. Hopefully it will show you that the edit box is not the problem.

Code: Select all

#include <irrlicht/irrlicht.h>
#pragma comment(lib, "irrlicht.lib")

using namespace irr;
using namespace gui;

class MyEventReceiver : public IEventReceiver 
{ 
public: 
   MyEventReceiver() 
   { 
   } 

   virtual bool OnEvent(SEvent event) 
   {
      if (event.EventType == EET_LOG_TEXT_EVENT)
      {
         fprintf(stderr, "%u: %s\n", event.LogEvent.Level, event.LogEvent.Text);
         return true;
      }
      else if (event.EventType == irr::EET_GUI_EVENT && event.GUIEvent.EventType == EGET_EDITBOX_ENTER) 
      {
         fprintf(stderr, "%s\n", core::stringc(event.GUIEvent.Caller->getText()).c_str());
         return true;
      }

      return false; 
   } 
}; 

int main(int argc, char* argv[])
{
   // event receiver displays the edit box text
   MyEventReceiver receiver;

   // create device and exit if creation failed
   IrrlichtDevice* device
      = createDevice(video::EDT_SOFTWARE, core::dimension2d<s32>(800, 600), 16, false, false, false, &receiver);
   if (!device)
      return 1; // could not create selected driver.

   // get the gui manager
   IGUIEnvironment* gui = device->getGUIEnvironment();

   // create a single edit box
   gui->addEditBox(L"", core::rect<s32>(10, 10, 300, 30));

   // get the driver so we can go on with our lives
   video::IVideoDriver* driver = device->getVideoDriver();

   while(device->run() && driver)
   {
      // try to draw everything
      if (driver->beginScene(true, true, video::SColor(255, 0, 0, 0)))
      {
         // render a full screen size image
         gui->drawAll();

         // end the scene
         driver->endScene();
      }
   }

   // release everything
   device->drop();

   return 0;
}