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

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.

Related

Make a Qt/C++ program show its file types as known on Windows

Using Qt 5.9 I codded a spreadsheet program and then created an installer for it by Qt Installer Framework (QtIFW2.0.1). Then I sent the program to many of my friends. They installed the app on their Windows machine and now using it, but they have all have a common problem:
when they save files of the app, those files are shown as "unknown" files on Desktop.
The problem is only with the shape and appearance of the stored files not their functionality, and they are opened by the app if double clicked.
The question is, what changes in the code is needed to have the program make its files' shape/appearance shown known?
For example, we offer the code a specific shape using an image file or like that, to be mapped on the stored files and that way they are shown known.
This has actually nothing to do with Qt or C++ itself. You just need to register your file extension in Windows shell, so it can be understood by other Windows components/shells.
Here is general information about File Types and File Associations under windows.
You need to make some Windows Registry entries which look like this:
example.reg:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\myfirm.myapp.v1\shell\open\command]
#="c:\path\to\your\app.exe \"%1\""
[HKEY_CURRENT_USER\Software\Classes\.myextension]
#="myfirm.myapp.v1"
Here you can read how it works in general
change myfirm.myapp.v1, .myextension and path to your .exe to your prefered names.
Now Windows will know what the files with extension .myextension should be opened by your app. And if you double click on this files your app will be run with path to file as an argument. You can get it in your main() function
To set icon for your extension add Registry entry in Software\\Classes\\.myextension\\DefaultIcon and set it default value to the full path to your app, so windows can get an icon for extension from your .exe app file.
You can also do it at runtime directly in your app:
QSettings s("HKEY_CURRENT_USER\\SOFTWARE\\CLASSES", QSettings::NativeFormat);
QString path = QDir::toNativeSeparators(qApp->applicationFilePath());
s.setValue(".myextension/DefaultIcon/.", path);
s.setValue(".myextension/.","myfirm.myapp.v1");
s.setValue("myfirm.myapp.v1/shell/open/command/.", QStringLiteral("\"%1\"").arg(path) + " \"%1\"");
EDIT: One more, to do it with Qt Installer look at the answers here

New to Xcode can't open files in c++?

I've been using windows in a class I've been taking but I am trying to run a basic code to figure out how to open/close/input/output from files on Xcode and the code I usually use on visual studios isn't working any idea why? thanks!
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream fin;
ofstream fout;
string input;
fin.open("inputFile.txt");
if(fin.fail())
cout << "File failed to open." << endl;
fin >> input;
fout.open("outputFile.txt");
fout << input;
}
Put your .txt files in the same directory where your main.cpp file is (or anywhere you like).
In Xcode go to Product > Scheme > Edit Scheme > Run (on the left) > Options (middle top)
Down under Options for "Working Directory" check “Use custom working directory” and set it to the directory where you .txt files are located.
To work with the files, you will have to specify just file names, e.g. in_file.open("inputFile.txt"); no path is necessary.
Here's a completely different approach: Have Xcode copy the input file for you.
Select your project in Xcode
Select Build Phases
Click the '+' button to create a new Build Phase
Select New Copy Files Build Phase
Select Products Directory
Click the '+' button to add your file
Click Add Other
Select your input file and click Open
Check the Copy items… checkbox and click Finish
Now every time you build your project, the input file will be copied to the same folder as the executable no matter where it is built. Of course, to see the output file, you'll still need to find the executable in Finder.
The answers don't really explain the problem so I thought I'd do that.
When you pass a relative path like "inputFile.txt" to file APIs, it's treated as relative to the working directory when the program is executed. This is the same as the 'working directory' when you use cmd.exe or Terminal.app or command lines in general. The Unix command pwd ("print working directory") displays the current working directory. On Windows running the command cd with no arguments performs the same function. (On Unix running cd with no arguments will change the working directory to the user's home directory.)
When you run a program from the command line, the command line shell sets the program's working directory. When you run a program from within an IDE, the IDE sets the working directory. Since, unlike on a command line, there's no obvious answer for what the IDE should set as the working directory, Visual Studio and Xcode set the working directory to different locations by default: Visual Studio sets the working directory to $(ProjectDir), the directory containing the Visual Studio project file; Xcode sets the working directory to the build products directory, i.e. the location the executable was written to.
Some possible solutions to your problem are:
Do not use a relative path, and therefore don't depend on the working directory. This isn't much help in making the program more portable, because the absolute paths will also differ between platforms, and so you will still have to 'configure' the program for each platform. In fact using an absolute path is worse, because it means your source code must differ, whereas it would be better to keep that difference confined to each platform's build configuration.
Configure the IDE to use your desired working directory. Visual Studio can be configured by right clicking the project, selecting Configuration Properties > Debugging > Working Directory, and setting the working directory to the desired path (potentially using Visual Studio build variables).
nepete's answer describes how to configure the working directly set by Xcode.
Configure the IDE's build process to copy your data files to an appropriate location. In Visual Studio you would do this in a C++ project by configuring the project's Properties > Configuration Properties > Build Events.
SSteve's answer covers how to configure additional build steps in Xcode.
I'm guessing you have inputFile.txt in the folder that contains your source code. That's not going to work. You need to put it in the folder that contains the generated executable. To find that folder, right-click on your app under Products and select Show In Finder.
This image shows what it looks like for a command line program. It also shows the Finder window that was opened. As you can see, it is a different folder than the one containing the source code.
As suggested by nepete, edit the scheme, but use $PROJECT_DIR as the custom working directory. Helps with moving the project around, or working in two different environments (e.g., home and office).
BTW. $PROJECT_DIR is one of the Xcode Environment Variables, and also helps with passing file names as command line arguments to programs (settable under "Arguments" in the scheme).
I've struggled with the same problem today. I wanted to add C code to my Swift project and my file pointer was always NULL.
Unfortunately, in XCode 9 for iOS app, I couldn't change the working directory. Changing Build phases didn't help me either. After 4+ hours of trial and error, that's what I've come up with finally and it works:
when copying files to XCode, I've chosen "Create groups", but I needed to choose "Create folder references":
I created a new objective-c file (.m) and copied all my C code there.
I left untouched .h files (XCode generated bridging header and my own .h file with public functions declaration). Now my project structure looked like this:
In my dict.m file in place of previous plain c fopen part:
FILE *dic = fopen("dictionary.txt", "r");
I added obj-C code:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"dictionary" ofType:#"txt"];
FILE *dic = fopen([filePath cStringUsingEncoding: NSUTF8StringEncoding], "r");
And it works now without any problem! It's just amazing!
ps I decided to write this answer in case it will help someone like me and will save them some time. If you know how to change working directory in XCode 9 for iOS, please, leave me a comment - now I am really curious why I can't find it.

qt creator can not load icon

I am a beginer of QT, I tried to add an action to a toolbar and I wrote as follows:
toolbar->addAction(QIcon("/icons/new.png"), "New File");
However, the image can not be loaded. Is that related to my debug path? I can see the button, but no images.
those codes are in test.cpp and my icons folder is in the same path with test.cpp
Paths are interesting.
If you are on linux, you just specified that the root of the drive has a folder called icons, and inside it it has a file called new.png.
If you were using that kind of a path on a website, it would chop off everything to the left besides the domain and subdomain names.
example.com/path/to/some/folder/index.html, processes link to /icons/new.png, and you end up at: example.com/icons/new.png.
The best way to handle paths correctly is to use common notations for relative paths (in most cases... in some cases, absolute paths make sense).
./ means the folder that I am currently in aka the working directory.
../ means the folder above me.
A leading / means the highest folder possible or the root folder, on Unix systems. It is also akin to giving an absolute path for a file.
No leading . or .. or / means the same as ./, or from the working directory.
And there are even more rules about this. See the wiki entry:
http://en.wikipedia.org/wiki/Path_(computing)
In Qt there is also the resource system, that embeds files into the exe itself and can give you a harder-to-change image or graphic on your program.
The notation to access this is:
:/ means the root of the qresource system.
And if you do decide there is a reason to use a backslash, be sure to escape it. Normally Qt will take any input with backslashes and convert it for you on the fly to forward slashes.
So to double check that the file is there, use QFile file("icons/new.png"); followed by if(!file.exists()){ qDebug() << "File is not found!" << file.fileName(); }
Sometimes I find it helpful to see where my program is when this is happening. Either using system("dir"); or qDebug() << QDir::currentPath();
http://doc.qt.io/qt-5.5/qdir.html#currentPath
You can also see what your initial working directory is by looking at your project properties for the project in Qt Creator under:
Projects (tab) > Run (tab) > Run > Working directory:
Usually it is the root of where your source code is and where your .pro file is located.
Hope that helps.
If you are using Qt resources then you need a colon:
toolbar->addAction(QIcon(":/icons/new.png"), "New File");`
if you don't use resources then yuo should use relative path. Remember that Qt Creator uses by default "build in different place" so you must make sure that icon is deployed in respective directory.

WxWidgets - Unable to load images

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.

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.