I've been trying to make a simple wxWidgets program with just a button with a picture on it. I've been able to make the button with the image on it easily enough, but my problem arises when including it.
So far, I've only been able to fetch the image during run-time (the image has to be in the same folder as the .exe file; otherwise, I get error 2: the system cannot find the file specified). With this method, I have no problems -- the program works just fine. What I'm trying to do, however, is to #include the file so that it is embedded during compile-time, so that it doesn't need to be available during run-time.
I've tried #including the file (both as .png and as .xpm), and I've also tried adding it to the resource includes (this is on Visual Studio 2017). Neither of these worked -- the first method still required the image to be in the same folder, and the second failed during compilation (as far as I can tell, it wasn't able to read the .xpm file).
Here is the relevant code, if it helps:
/*relevant includes*/
#include "happyFace.png" //this isn't working. the file is still needed
||
#include "happyFace.xpm" //ditto
/*I have also tried putting these lines in the resource includes.*/
/*code*/
wxInitAllImageHandlers();
wxBitmap bitmap("happyFace.xpm", wxBITMAP_TYPE_XPM); //only works in same directory at run-time
||
wxBitmap bitmap("happyFace.png", wxBITMAP_TYPE_PNG); //ditto
wxButton *button = new wxButton(this, ID_BMP_BUTTON);
button->SetBitmap(bitmap);
//the rest of the button programming and stuff
Sorry if I haven't provided enough information; I can provide more if necessary. I would really appreciate any help. Thanks!
Two possibilities... Number 1 is simplest. It's been a long time since I wrote the code I'm looking at, so the details are fuzzy.
In Visual Studio, Solution Explorer, add the image into the resource files. Assume the name of the resourse is sample.rc. Then it can be used like so to set the main icon...
SetIcon(wxICON(sample));
Method 1 must be used in order for MS Windows Explorer to display the main icon. I do not remember how to use .rc resources for other things, but it should be easy to figure out.
I did it this way before I discovered VS resource (.rc) files. Compile the file-image into the program "by hand." In other words, write a program that will read an image file and produce bit-for-bit copy in a .cpp file. Then compile that .cpp into the program. Here I have the file-image in memory as an object named dj::main_cursor. Note that the in-memory version is a bit-for-bit copy of a .cur file.
dj::captured_file &c1file(dj::main_cursor);
wxMemoryInputStream cistr(c1file.contents, c1file.size);
cursor1 = wxCursor(wxImage(cistr, wxBITMAP_TYPE_CUR));
FYI, I defined the structure dj::captured_file like so:
struct captured_file {
const char *name;
const unsigned long size;
const void *contents;
captured_file(const char*fn, size_t sz, const void*c)
: name(fn)
, contents(c)
, size(sz)
{}
};
See also, Embedding PNG Images into Windows RC Files
I found some other documentation.
Resources and Application Icon All applications using wxMSW should
have a Windows resource file (.rc extension) and this file should
include include/wx/msw/wx.rc file which defines resources used by
wxWidgets itself.
Among other things, wx.rc defines some standard icons, all of which
have names starting with the "wx" prefix. This normally ensures that
any icons defined in the application's own resource file come before
them in alphabetical order which is important because Explorer
(Windows shell) selects the first icon in alphabetical order to use as
the application icon which is displayed when viewing its file in the
file manager. So if all the icons defined in your application start
with "x", "y" or "z", they won't be used by Explorer. To avoid this,
ensure that the icon which is meant to be used as the main application
icon has a name preceding "wxICON" in alphabetical order.
http://docs.wxwidgets.org/3.1.0/page_port.html
Here is how you should do it:
#include "happyFace.xpm"
wxBitmap bitmap = wxBitmap( happyFace ); // assuming the variable name is "happyFace" inside the xpm
Then you will use bitmap object just like usual. Assuming that the file happyFace.xpm is available for compilation.
Related
Hey guys I'm new in c++ wxwidgets programming.
I would like to know the easiest way to put an image into a button.
I tried :
button1 = new wxBitmapButton(side_panel, wxID_ANY, wxBitmap("image.png",wxBITMAP_TYPE_PNG), wxPoint(150,30), wxSize(30, 30),wxBORDER_NONE);
But I always get the same error:
If you expand the error dialog you see, you should see more information about the error, but my guess is that the image simply can't be found. You should check that the file image.png indeed exists in the current working directory of your program, i.e. the directory that you run it from, assuming you don't change it later.
You should also actually check for errors in your programs, even simple ones, i.e.
wxBitmap bmp("image.png");
if (!bmp.IsOk()) {
... handle the error somehow instead of blithely using an invalid bitmap ...
}
I am writing an application using the Qt framework. In the display, I have to show multiple information, but using different types of font of the same family, Montserrat.
What I have done so far to load the fonts is:
int ultralightid = QFontDatabase::addApplicationFont(":/Montserrat_UltraLight.tff");
QString UltraFont= QFontDatabase::applicationFontFamilies(ultralightid ).at(0);
QFont font1(UltraFont,QFont::Normal);
font1.setPixelSize(50);
int lightid = QFontDatabase::addApplicationFont(":/Montserrat_Light.tff");
QString LightFont= QFontDatabase::applicationFontFamilies(lightid).at(0);
QFont font2(LightFont,QFont::Normal);
font2.setPixelSize(150);
label1->setFont(font1);
label2->setFont(font2);
label1->setText("bla bla");
label2->setText("bla bla");
The font sizes are correct, but the font itself it is not. From what I have noticed (trying with Hairline_Montserrat,Light_Montserrat,UltraLight_Montserrat), it is as if the fonts have a sort of priority. If I declare them all, all the fonts are the Light one, if I comment that font type, all of them are Hairline one, otherwise (last priority) the labels use the ultralight font.
I have tried adding other font type (from other families) and in that case my code works correctly.
If I use
qDebug()<<QFontDatabase::applicationFontFamilies(ultralightid);
qDebug()<<QFontDatabase::applicationFontFamilies(lightid);
both of them print the family "Montserrat".
I use the qrc file and the AUTORCC flag in the CMAKE (it should be similar using qmake) and all the file are uploaded correctly.
Do you know if there is another way to add fonts of the same family? Or is there something I am doing wrong?
Here are the fonts:
https://www.onlinewebfonts.com/download/9d31c906a6cc6064bbe7d33d51058317 light
https://it.allfont.net/download/montserrat-light/ ultralight
This is an old question but I was just struggling with exactly the same problem when trying to load normal, bold, ... versions of a font family in Qt.
I solved the problem (although in a somewhat hacky way) by simply giving each of the ttf files a different family name. I used Typograf, simply open the font, right click to open properties and then click rename. There are probably many other tools that do this too.
You don't need to manage font files from one family separatelly.
I suggest this solution:
Create a folder with all ttf's of the same family.
Load all files from the folder via id = QFontDatabase.addApplicationFont(path)
Collect all font families from these files via QFontDatabase.applicationFontFamilies(id)
Check if only one and desired family is loaded, and the family name is exactly the same as requested, or warn the user about these errors.
Create font object font = QFont(family)
Then for example, font.setItalic(True). If Italic version of family is loaded, it will be used, otherwise it will be created from Regular by QT.
I want to create toolbar items and paint them from images in program memory rather than from files on disk. I would prefer to embed the images using a resource file (.rc), but if I need to roll my own somehow that's okay too.
The image files are .ico and .png.
Assuming I can use stuff from the .rc file, how do I complete this code?
void MyFrame::AddToolBarItem(int ID, wxSize sz, const char* file, const char* short_help, const char *long_help) {
const char *end = file+strlen(file);
const char *dot = std::find(file, end, '.');
if(dot != end) {
// It's an external file, with an extention, like .ico or .png
wxImage im(file);
im.Rescale(sz.x, sz.y, wxIMAGE_QUALITY_HIGH);
wxBitmap bmp(im);
my_tool_bar->AddTool(ID, short_help, bmp, long_help);
} else {
// It's a resource
// What now, StackOverflow???
}
}
EDIT: Okay, I'll make it easier. Forget about Rescale. I can do that with Gimp picture editor. Assume the images are the right size. You may also assume they are .ico or whatever format is convenient to wxWidgets.
EDIT 2: I am accepting an answer, but I have decided it is best just to embed the image "by hand", avoiding the .rc concept altogether. I wrote a little program to create a .cpp file with static initializers, but one can find them on the net. When compiled into the program, the .cpp file creates a copy of the image file in read-only memory. The .rc file is a Windows-specific thing, so it would be a good idea to avoid using it for custom icons and cursors, for portability. However, it does make sense to have a .rc file in the MS project that contains only the line "#include <wx/msw/wx.rc>" That will give access to some stock cursors and so forth that are available by default on other platforms.
There is no support for loading PNG from resources in wx itself but it's easy to do it in your code, see http://wiki.wxwidgets.org/Embedding_PNG_Images#Embedding_PNG_images_into_Windows_rc_file
The Bitmaps and Icons overview gives a pretty good explanation of this. Basically once you have embedded the resource in your .rc file all you need to do is:
wxBitmap bmp(wxBITMAP(bmpnameinrcfile));
similarly for ico
wxIcon icon(wxICON(iconameinrcfile));
I'm interested in writing a small utility in C++ for Mac OS X to read, parse, save (over)write a file. I don't need any GUI, menus, or windows.
What type of project template do I need to start with in XCode?
How can I access the file that is passed in? (It's passed with Apple Events openFile, right?)
I've done a little C++ but nothing on Mac. Links appreciated, code samples appreciated more.
How do you intend to pass files to your application?
If it's via the command line then you would use the Command Line Tool template and access the command line parameters just as you would on any POSIX platform (argc and argv).
If you want to pass files to your application using Finder, say, by dropping files onto the application icon, then you would use the Cocoa Application template.
The Info.plist file contains your application configuration and supported document types, similar to the registry on Windows.
You configure Info.plist via the "Info" tab of your Project Settings (It's the top-most file in the file navigator in XCode). Click the "Add" button in the lower right, then select "Add Document Type" to add a document type that your application will accept. To accept all documents, set the document name to All and set the extension to *. More info is here.
Add a LSUIElement key in your Info.plist, and set its value to YES to indicate that your application has no UI. This key is also displayed as "Application is agent" in XCode. More info on LSUIElement is here.
In your MainMenu.xib, you can delete the Window and Font Manager objects that are there by default, since you won't be needing them.
Rename the AppDelegate.m file to AppDelegate.mm, so that it's compiled as Objective-C++. This will allow you to use C++ code in that file.
In the applicationDidFinishLaunching: delegate method, add [NSApp terminate:nil]; so that your app quits immediately when it's done its work.
Add the following method to AppDelegate.mm:
- (BOOL)application:(NSApplication*)app openFile:(NSString *)filename
{
NSLog(#"Opening file %#", filename);
char* cFilename = [filename UTF8String];
// Your C++ code goes here
return YES;
}
That's it. The rest is your C++ code. You can add any C++ code to AppDelegate.mm that you want. E.g.:
#include <string>
#include <iostream>
#include "MyCppFileProcessor.h"
- (BOOL)application:(NSApplication*)app openFile:(NSString *)filename
{
std::string cFilename([filename UTF8String]);
std::cout << "Processing file: " << cFilename << std::endl;
MyCppFileProcessor fileProcessor;
fileProcessor.processFile(cFilename);
return YES;
}
This code will run whenever you drop a document onto your Application's icon in Finder.
1)Use the Command Line Tool template. There are several options for this template. You may select C++ from the menu.
2)As far as I know IOstream will work just fine. Also, there's an argument parameter on your main() function, you may get the file name from these args.
http://www.cplusplus.com/reference/iostream/
I have some code which shows a simple dialog box and handles user action (written using plain WinAPI).
// Display dialog and handle user action
LRESULT choice = DialogBoxParam(NULL, MAKEINTRESOURCE(AP_IDD_DIALOG), NULL, (DLGPROC)DialogCallback, NULL);
Is there any way to hardcode the resource file dialog.rc, which is used to build the dialog ?(I would like to get rid of .rc files and I'm pretty sure there is a way, yet I don't know what it is :)
Edit
Also, does someone have any ideas on converting existing .rc files into hardcoded resources? Is this possible?
*.rc (resource) files are source code, they are compiled with the resource compiler and linked into your object (.exe/.dll)
You don't need to ship the resource file or have it present with your app to run it.
If you want to move to programmatically defined windows rather than templates then you might want to be looking at QT/wxWidgets. But thats a fair chunk of overhead for 1 dialog!
I'm surprised I couldn't find an existing app to do this sort of thing, enough hits on google with people trying to do this.
Ok, so the DLGTEMPLATE is a variable length blob of data, normally you let the dialog function pull it from the resource bundle for you, but instead you want to store it in your program.
You need to change your static lib to have a new function to decode some 'blob' back into the dlgtemplate, and you need to generate the blob. (or add the blob in your code without decoding which I don't want to think about right now)
The following code will give you the DLGTemplate data you need to imbed in your app. (cut from larger project)
HGLOBAL LoadResourceImpl(wchar_t *resource, wchar_t *type)
{
HRSRC handle = FindResource(hInstance, resource,type);
if (handle)
{
HGLOBAL hResource = LoadResource(hInstance, handle);
if (hResource)
return LockResource(hResource);
}
return 0;
}
DLGTEMPLATE * LoadDialog(wchar_t *resource)
{
return (DLGTEMPLATE *) LoadResourceImpl(resource,RT_DIALOG);
}
DLGTEMPLATE * LoadDialog(int resource)
{
return (DLGTEMPLATE *) LoadResourceImpl(MAKEINTRESOURCE(resource),RT_DIALOG);
}
Make an app that includes your resource - use the appropriate LoadDialog to get the data.
Now "write out" that blob in a format to include in your app -
step 1 - find out how much data there is by traversing the structure to find the total size including all the controls (control count is in DLGTEMPLATE::cdit)
step 2 - convert the data to something you can compile into your code - like HEX
Add to your static library a new 'HEX' to DLGTEMPLATE method and the hex string you made using the other app.
Can we hard code the .res file into the program?
the resource compiler converts .rc into .res
use a hex dump tool (eg. winhex) to translate the .res into bytes array
(represented in C source code).
add the source code file in the project and compile in the executable.
locate the dialog resource position from the array and use DialogBoxIndirect.
DialogBoxParamIndirect can be used instead. It takes as a parameter the dialog template. Raymond Chen's blog has an example of building a dialog box at runtime rather than from a resource using the DialogBox*Indirect API's.
Per MSDN, dialog box resources are basically composed of the DLGTEMPLATE and DLGITEMTEMPLATE structures. So you should be able to use the resource API's (FindResource, LoadResource, and LockResource) to get at the underlying bits of an existing dialog resource, and embed that within your code.
Note that this is a lot more painful than using the .rc file. It's much more difficult to make changes to your layout, and it's also much less localizable, since localization would now require a code change to update the template in code.
If it's a simple dialog, why use the DLGTEMPLATE at all?
Nothing stops you from simply doing ::CreateWindow'ing those controls directly. If it's a simple dialog with 2-3 buttons and a couple text fields, simply call ::CreateWindow, passing in the window class of whatever common control you're using.
This is essentially what the DialogXxxxx functions do anyway. DLGTEMPLATE is a convenience for declaratively laying out your forms, and having the boilerplate make the appropriate CreateWindow calls, etc.