WxWidgets - Unable to load images - c++

I recently started working with WxWidgets (2.9.4) and was working through a tutorial I found, but it seems that I'm unable to load any images. I've already properly used the handler (for PNG) and the problem happens at run-time. Below is an image of the popup that is displayed when attempting to run the program.
Here is the code:
wxPNGHandler *handler = new wxPNGHandler;
wxImage::AddHandler(handler);
wxBitmap exit;
exit.LoadFile(wxT("exit.png"), wxBITMAP_TYPE_PNG);
wxToolBar *toolbar = CreateToolBar();
toolbar->AddTool(wxID_EXIT, exit, wxT("Exit"));
toolbar->Realize();
Connect(wxID_EXIT, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(mainWindow::exitProg));
Any help is appreciated.
EDIT: I forgot to mention that when I click Cancel, this happens:
I placed the exit.png file in the build directory (/Debug or /Release) as well as the source code directory, but it still has yet to see it.

What is your working directory?
If you are using visual studio and running using the interface ( F5 or ctrl-F5 or the little run button in the toolbar ) then your working directory is the folder containing the project file. So try copying your image file there.
Or open a command window, cd to one of your build directories, and run your app from the command line.
In general, to avoid this sort of problem, I alter the project properties so that the executable is NOT stored in one of the build folders, but in a new folder ( which I usually call 'bin' - my unix roots are showing! ) and also alter the debugging properties so that the working directory is the bin folder.
There are a couple of advantages to this technique:
Both the release and trhe debug version use the same folder, so you only need one copy of any extra file, like your image file.
It is easy to see the executable and extra files in the working directory without being distracted by all the .obj files that end up in the build folders
IMHO this is well worth the little extra trouble in maintaining non default project properties.

First of all, to avoid problems deep inside wxToolBar, always check the return code of LoadFile() or, alternatively, use wxBitmap::IsOk() to check that the bitmap was successfully loaded.
Second, while adding the handler explicitly as you did is perfectly fine, I'd recommend to just call wxInitAllImageHandlers() as it's simpler and has no real drawbacks unless you are looking to create the smallest program possible.
Finally, to address your real problem, the file clearly doesn't exist at the path you're loading it from. You can, of course, solve this by being careful not to change your working directly (or restore it after changing it) in your program and by placing the file in the correct place. But this is, as you discovered, error-prone, so a better idea is to always use full paths to your resources. To construct them, you will find wxStandardPaths useful, in particular its GetResourcesDir() method.

Related

How to add and use .zip (or .pak) files to c++ project?

I'm compiling CEF (Chromium Embedded Framework) for our local html5 presentation.
I should say I'm very new for all this (CEF and C++).
I've already optimized cefclient project for the presentation, but I need to embed all html/js/css/etc files into project (reading from local storage is not an option).
As I understood, I should use .zip or .pak (renamed zip) files to embed. But how can I use them inside the project?
Should I use some lib for unzipping (zlib?) or there is another popular way? And how can I be sure that files will be compiled into project?
Sorry for such basic questions but there are very few information about this (or google hates me today).
Thank you for any help!
UPD: found great tool - WBEA (http://asterclick.drclue.net/WBEA.html), it looks like exactly what I want to, but works pretty slow (with JS).
UPD 2: It turns out that there are many ways to make HTML5 desktop application, for example Node-Webkit.
Here is an article that compares some of them http://clintberry.com/2013/html5-apps-desktop-2013/
You need:
Create zip file whitin your resources.
Embed it as win32 resource (after this step you will get correct executable with .zip file inside).
Create custom scheme handler to access this zip file.
CefZipReader class will be handly to implement handler from step 3.
Look around, may be something like what you want already exist somewhere.
This sounds very similar to self extracting installers.
No need to compile anything, just concatenate the zip to the end of the executable. All you need to do is find the offset at runtime from the start of the executable. This can be done easily by writing a large magic number and looking for it later.
Example Linux:
cat app magic_number data > new_app
Example Windows:
copy app.exe /B + magic.dat /B + data.dat /B new_app.exe

Why is SDL not loading my images when main application is accessed via shortcut?

I have recently created a program using C++ and the SDL library. Originally, all the images and DLLs were in the same folder as the main application. I wanted to make the main application easier to find, so I instead moved all the images into their own folder and modified my source code to find them in the correct folder. So far, so good. The main application still remains in the same folder as the DLLs.
I created a shortcut to the main application and put that it's own folder. I changed the target to %windir%\system32\cmd.exe /q/c start "" ""%SystemRoot%\explorer.exe %UserProfile%\Desktop\Cupcake Corner Build 2.0 (exe test)\dependecies\Cupcake Corner.exe" in an attempt to make a universal shortcut, so that the shortcut would work for any user I send the files to.
After all said and done, I've ran into a problem. If I open the main application itself, it will load the images and work perfectly. If I try to the main application via its shortcut, the window will open correctly and display the correct title, although none of the images will load. I tried moving some files around to see if the shortcut would see them if I put the resource folder elsewhere, but so far no luck.
images here -> C:\Users\Admin\Desktop\Cupcake Corner Build 2.0\dependecies\resources
main app/dlls here -> C:\Users\Admin\Desktop\Cupcake Corner Build 2.0\dependecies\
shortcut here -> C:\Users\Admin\Desktop\Cupcake Corner Build 2.0\
I am using Microsoft Visual Studio Express 2010. I think it has something to do with the way I have my project directory set in project options, but I'm honestly baffled at this point. Can anyone point me in the right direction?
Generally, when dealing with files in an application (that the application knows internally, at least), you will want to have absolute paths.
The best way to solve this is by having a (set of) function(s) that add the absolute path (found by GetModuleFilename(0, ...) or from some configuration for example in the registry)
std::string myfiles_root_path = FindMyFilesRootPath();
std::string MakeFullPath(const std::string &filename)
{
return myfiles_root_path + filename;
}
The function FindMyFilesRootPath() uses one of the methods above to find the appropriate path, and filename is the name of a file local to your application.

c++ boost library cannot open file

I tried to work with the boost library to read/write configuration files but I just don't get it.
I even can't run the example code from boost.org (5 Minute Tutorial)
http://www.boost.org/doc/libs/1_49_0/libs/property_tree/examples/debug_settings.cpp
I've downloaded the boost_1_49_0.zip package and unzipped it to my c++ program folder. The code compiles (TheIDE - U++) but it always says "Error: debug_settings.xml: cannot open file" which basically means that the program works, but runs into the exception.
I didn't change the code, I just copy and pasted it to get a working example which I could try to understand then. But I don't even get this one to work. (Since it's exactly the same as in the link, I don't paste the code here... unless you think it's better.)
Please help me... or point to a different way to store variables in a file with some kind of structure (I wan't to learn a way that works for windows and linux, because some of my apps are cross-platform.)
Thanks.
EDIT: debug_settings.xml is in the same folder as the .cpp file
EDIT2: Working now, the debug_settings.xml is now in the folder where the executable is stored. (in my case, U++/TheIDE it's C:\upp\out\MyApps\MINGW.Debug.Debug_Full.Sse2 for debugging)
The configuration file would need to be in the working directory of the executable when it's running.

Where to start for writing a shell script for copying elements into main app xcode4

I am looking for some documentation or tutorial for copying files from a given directory into the app created by xcode at build time, before it is run.
At first I have tried to copy files into the derived directory, hoping that everything resides in there would be automatically added to the app, but I was wrong.
So I am looking for a script because the original dir may change its name, second the script could be customized by another xcode 4 user with its src dir path etc.
The things is I don't know how to start, which language etc. I am quite confident with shell script, but maybe there's a better option.
Second, I am trying to figure out which command could add a file in the already built app.
thanks
That answer didn't really help - the BUILT_PRODUCT_DIR isn't where most stuff goes.
Ultimately, I found you just need to do:
Add the following to the very end of your script (or get your script to write directly to the output location):
cp ${DERIVED_FILE_DIR}/[YOUR OUTPUT FILES] ${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
...but there's a lot of other things I tried. More thoughts and ideas here: http://red-glasses.com/index.php/tutorials/xcode4-a-script-that-creates-adds-files-to-your-project/
You want a Run Script or Copy Files build phase. Select your main project in the navigator, then select the app's target. Click the Build Phases tab. Click the Add Build Phase button at the bottom of the window and choose the appropriate phase.
By "appropriate" I mean if you really want to run a script, you'll use a Run Script build phase and use Xcode-provided environment variables like $BUILT_PRODUCT_DIR (see the documentation or hit build and examine the full output of an empty script in the build log) to figure out your target folder. If all you want to do is copy files (no real processing), the Copy Files build phase already knows how to locate the app bundle's proper folders depending on what you're copying (Resources, Frameworks, etc.).

How to make XCode put required resources in "build" folder?

I am trying out lua script with C++ in Mac OS X. I was finding a way to make the program returning the current working directory. That's no problem with getcwd, but then I came one thing:
My foo.lua stays at its initial path only. When I compile program, it is not being copied over to the build/Debug directory. Sure, I can grab my script there, but that's just impractical. XCode or any IDE should carry resources to the build zone. XCode does this automatically with iPhone app, but this seems to be a different case. For this case, how to command XCode to put the respective resources in the build directories?
int main (int argc, char * const argv[]) {
...
...
luaL_dofile(luaVM,"/Users/yourNameHere/Desktop/LuaSandbox/LetsTryLua/foo.lua");
//typing the whole absolute path here is just ugly and impractical.
...
...
printf("working directory: %s", buffer);
//output is: working directory: /Users/yourNameHere/Desktop/LuaSandbox/LetsTryLua/build/Debug
...
...
Rather than hard code the path to your Lua script you may want to use the NSBundle API's to find it:
NSBundle * mainNSBundle = [NSBundle mainBundle];
NSString * luaFilePath = [mainNSBundle pathForResource:#"foo"
ofType:#"lua"
inDirectory:NULL
forLocalization:NULL];
luaL_dofile(luaVM,[luaFilePath UTF8String]);
This will find it in the bundle's folder (if you added the "Copy Bundle Resources" build step to your target as the above poster suggested.
Because you're using a .lua file as a resource, I suspect that isn't recognised as a standard resource type and hence it hasn't been automatically copied. You should be able to do this though by adding an extra Copy Bundle Resources build step to your target and then add your file to it in the project view.
If you're creating a command line tool that is not a bundle, then there's never going to be a good solution. If you're creating a regular app then the aforementioned solution will work, but you're going to have to stop assuming that your working directory is set to anything even remotely meaningful at any point in time and use the appropriate methods for finding resources stored within your bundle.