MFC resource-script file: Control description replaced by Control ID - mfc

I am maintaining an MFC project, there is something strange about the .rc file. I inserted an menu in Resource View and I added two items in this menu.
Visual Studio assigns two IDs to these two items. Assume that the ID is 1000 and 1001. In resource.h,we can find #define ID_MENU1_SUB1 1000 and #define ID_MENU2_SUB2 1001, this is okay. But in .rc file:
IDR_MENU MENU
BEGIN
POPUP "MENU1"
BEGIN
MENUITEM "Sub1", ID_MENU1_SUB1
MENUITEM "Sub2", 1001
END
END
Why is ID_MENU1_SUB2 automatically replaced by 1001, even if the compilation has no problems. How can we avoid this.

Related

newbie: Code to show/hide a STATIC TEXT object in Visual C++ MFC app

I ran into a newbie problem with my first VC++ MFC app (actually, I ran into many problems, but RTFM and DuckDuckGo helped to solve them without crying here for help. Except this one!). Bear in mind that I am playing with this as a tutorial for myself, kind of a learn by example project, and I have a few years of Win GUI app programming experience in Deplhi/Lazarus, and now I am attempting to transition into VC++, simply for my own curiosity. While I am also good with C language programming, I have significantly less experience with C++. So the new programming environment and the less-known language together pose as my obstacle.
Here is what I did:
In a recently installed Visual Studio 2019 Community with only the Windows App development in C++ components selected, started a new project, chose C++ MFC App (Build apps with complex user interfaces that run on Windows.). Set application type to Dialog based, turn off all User Interface Features so only Thick frame is checked (unchecked System-menu, unchecked About-box), turn off all Advanced Features so only Common Control Manifest is checked (unck Printing and print preview, unck Activex controls, unck Support Restart Manager), clicked FINISH.
This prepared me an app with a single small main window, OK and Cancel buttons in its lower-right corner, and a STATIC TEXT item in the middle-center reading something like "TODO: add your own items here". Project name is TutMFC01p.
My goal was to hide that STATIC TEXT when I click one of the buttons, and make it visible again when I click the same button again.
It took me some time to realize that I should not fiddle with the OK and Cancel buttons to add them this functionality, and clicking either of these two buttons also quits my app (hence, no chance to click again). So I placed a new button on the dialog and worked with that instead. Clicking my button while my app was running did absolutely nothing - which was exactly what I wanted.
Double-clicking my button in the Dialog Editor dropped me into Source Editor with a new function autogenerated at the bottom of TutMFC01pDlg.cpp.
void CTutMFC01pDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
}
Allrighty, so this is where I will add the code of what the button is supposed to do.
It also injected an ON_BN_CLICKED line to the MESSAGE MAP, which now looks like this.
BEGIN_MESSAGE_MAP(CTutMFC01pDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CTutMFC01pDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
Allrighty again. So this is the way to tell the system that clicking my button should run the code given in CTutMFC01pDlg::OnBnClickedButton1().
The way I first tried to complete my goal was to alternate the STATIC TEXT object between the TRUE and FALSE value of the VISIBILE property upon the click of my button. A Delphi/Lazarus way of doing it is a single line of code like mainform.mystatictext.visible := not mainform.mystatictext.visible but I was not able to find a way to directly reference the property of an object and change its value with a simple assignment operation. What I found instead is that the way to hide objects is using the ShowWindow() method. I also run into difficulties trying to point this (or any other) method to the STATIC TEXT object, because apparently it has an ID of IDC_STATIC, which, apparently, cannot be referred to, as all static objects have this same ID. To simplify the task ahead, instead of hiding the STATIC TEXT I settled for hiding the button itself, and ended up with this code:
void CTutMFC01pDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CWnd* pMyButtonObj = GetDlgItem(IDC_BUTTON1);
pMyButtonObj->ShowWindow(SW_HIDE); //or SW_SHOW
}
This compiles and works very well. Obviously, once the button is pressed and disappears from the window, there is nothing to press again in order to unhide what was hidden. So I tried to move on from this already working code and modify it to act on the STATIC TEXT instead of the button itself. Logic suggested (my logic, anyways) that in order to gain the ability to refer to the ID of the STATIC TEXT, I need to assign a different ID to the STATIC TEXT. Something I can refer to. Something other than the not referrable IDC_STATIC. So I selected the STATIC TEXT object on the Dialog Editor, and in its Property palette I changed the value of the ID property from IDC_STATIC to IDC_STATIC1. This strangely has also changed the NAME property of the object to IDC_STATIC11. Earlier the NAME was IDC_STATIC1. Then in the code of OnBnClickedButton1() I replaced IDC_BUTTON1 with IDC_STATIC1, but that fails to compile complaining that there is no such object. Same happens when tried with IDC_STATIC11.
A little experimenting revealed another phenomena I am unable to explain (or understand). Similarly to how I changed the ID of STATIC TEXT, with my button selected in the Property Editor, I changed its ID from IDC_BUTTON1 to IDC_HideBtn. This also changed its NAME property.
Saved All, rebuilt project, and clicking my button still made it disappear, exactly as it was working before. HOWEVER, the source code of OnBnClickedButton1() and the MESSAGE MAP did not get updated to refer to the new ID, IDC_HideBtn, they still refer to IDC_BUTTON1, same as before.
void CTutMFC01pDlg::OnBnClickedButton1()
{
//TODO: Add your control notification handler code here
CWnd* pMyButtonObj = GetDlgItem(IDC_BUTTON1);
pMyButtonObj->ShowWindow(SW_HIDE);
}
But at this point, IDC_BUTTON1 should be a non-existing ID. Compile should fail. Yet it compiles fine, and it works fine.
QUESTIONS:
Why does the code compile and work with IDC_BUTTON1 in the source while the ID of the button is now IDC_HideBtn?
What can I do to be able to address the STATIC TEXT item as the argument to GetDlgItem() the same way as I could do with IDC_BUTTON1?
If STATIC TEXT items are not supposed to be programmatically changed then what other kind of item could I use instead? In Delphi/Lazarus there is a LABEL object similar to STATIC TEXT, but designed to get different Caption or other values many times while the program runs. In the toolbox of the Dialog Editor I see nothing like that, only STATIC TEXT. Or should I use an Input field instead, to display text in the dialog window?
Is there a way to implement the button click method in the way I initially tried to do the Delphi/Lazarus way? Changing the target object to visible from hidden, and to hidden from visible. Preferrably as a one-liner.
Is there NO WAY to directly refer to the property of an object and change its value with an assignment operation? Or only I did not find it how?
I have some small corrections (as I think), and I wanted to issue them as comments, but according to the comment policy it is better to post an answer despite that the answer has already been given.
Question 2:
It's strange that VS didn't add a new define for IDC_STATIC1 in resource.h on renaming a CStatic component (after all VS created a new id for a new button).
But of course, manual editing of resource.h is a very frequent procedure during programming with MFC, but it is necessary to update the _APS_NEXT_CONTROL_VALUE (and much less often _APS_NEXT_COMMAND_VALUE ) definition so that it points to a new correct value (not equal to previous definitions).
Question 3:
But you can write in you .rc file something like this:
BEGIN
DEFPUSHBUTTON "OK",IDOK,209,178,50,14
PUSHBUTTON "Cancel",IDCANCEL,263,178,50,14
CTEXT "TODO: Place dialog controls here.",IDC_MidTextObj,13,96,300,8
PUSHBUTTON "Hide object",IDC_HideBtn,135,106,50,14
END
and then in CTutMFC01pDlg.cpp:
void CTutMFC01pDlg::OnBnClickedHidebtn()
{
if (CWnd * pMyStaticObj = GetDlgItem(IDC_MidTextObj))
pMyStaticObj->ShowWindow(!pMyStaticObj->IsWindowVisible());
}
Question 4:
Also you can use the the DoDataExchange mechanism for getting/setting text for components like CStatic, CEdit, etc., and you can use ON_UPDATE_COMMAND_UI macros for enabling/disabling components.
But the basic way is to get a component as a CWnd class:
CWnd * pMyStaticObj = GetDlgItem(IDC_MidTextObj)
or get the component explicily:
CStatic* pMyStaticObj = static_cast<CStatic*>(GetDlgItem(IDC_STATIC1));
(don't use dynamic_cast here)
and then call methods of this fetched instance.
Thanks to the comments my question received, I could refine the direction of my web searches and also examine other files in my project folder to identify where trouble originates from, and understand how pieces of my MFC app fit together. Also, sometimes the inner workings of Visual Studio 2019 require a little manual editing help.
ANSWER 1)
All those IDC_xyzwq identifiers I can assign to the object in its property palette (values are selectable from a list) are predefined macros pointing to their respective numeric value. These live inside the resource.h file of the project. Unfortunately, VS2019 never allowed me to open this file as readable text - it always complained that the file is already open and asked me if I want to close it instead. To study the contents, I actually had to close my VS2019 solution, and open the resource.h file in a text editor. Here is what I found in there:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by TutMFC01p.rc
//
#define IDD_TUTMFC01P_DIALOG 102
#define IDR_MAINFRAME 128
#define IDC_BUTTON1 1002
#define IDC_ButtHide 1002
#define IDC_HideBtn 1002
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
So it seems that each time I invented a new ID for my button and entered it in the Property Palette, VS2019 injected a new macro definition into the resource file, assigning it to the same numerical value of 1002. But other than auto-creating such entries, Visual Studio performs no maintenance on them and it is the responsibility of the programmer to keep order there. Which requires that the programmer understands what is what, and where it is stored in the project files.
So, even though my button object already had the ID value of IDC_HideBtn in its Property Palette, the earlier IDs of IDC_ButtHide and IDC_BUTTON1 were still valid and referred to the same numeric value of 1002, hence the source code using the old ID compiled, and the button worked fine.
Mind you, I also had to manually replace the button ID NAME to the chosen one in my apps MESSAGE MAP in TutMFC01pDlg.cpp before Visual Studio could reopen my solution/project. See the next section of my answer too.
ANSWER 2)
IDC_STATIC being a peculiar ID with some special treatment, I cannot just invent and type-in any new name into the ID property field of my STATIC TEXT item. More precisely, I actually CAN invent any new ID and enter that into the property field, but Visual Studio DOES NOT automatically generate the corresponding new macro definition in resources.h, most likely because it does not know what numeric value to assign to an object that is supposed to have no numeric value (as it was supposed to have the special value of -1). So instead of entering a new name in the ID property field, the programmer should close the solution, and manually edit the resources.h file in a text editor. YES, against all warning and discouragement in Microsoft Documentation and by seasoned developers, in this particular case it must be done manually. (Or at least, I do not know a better way than directly editing the resource file as text.) Here is what I changed my macro definitions to, by removing the two obsolete and unwanted button identifiers with the value of 1002, and manually adding a new definition entry intended for my STATIC TEXT item - with a numeric value that was not in use by any other entry. In my case, 1001 was not yet used, so that is what I assigned to my invented ID of IDC_MidTextObj.
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by TutMFC01p.rc
//
#define IDD_TUTMFC01P_DIALOG 102
#define IDR_MAINFRAME 128
#define IDC_HideBtn 1002
#define IDC_MidTextObj 1001
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
With these changes saved in resource.h I could close my Text Editor and reopen the solution/project in Visual Studio. Then I could select the STATIC TEXT item in the UI Editor, and in its Property Palette, in the field of the ID property, I could drop down the list of values and select my prepared value of IDC_MidTextObj. Mind you, there is another way to do this, by manually editing the .rc file of the Dialog. Which you will likely need to do for other reasons anyway. See next section of my answer.
ANSWER 3)
Here is the relevant part of my TutMFC01p.rc file.
IDD_TUTMFC01P_DIALOG DIALOGEX 0, 0, 320, 199
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
EXSTYLE WS_EX_CLIENTEDGE | WS_EX_APPWINDOW
CAPTION "My VisualC++ Tutorial App 01"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,209,178,50,14
PUSHBUTTON "Cancel",IDCANCEL,263,178,50,14
CTEXT "TODO: Place dialog controls here.",IDC_STATIC,13,96,300,8
LTEXT "Hello MFC!",IDC_STATIC,22,33,86,8,WS_DISABLED
PUSHBUTTON "Hide object",IDC_HideBtn,135,106,50,14
END
I could just change the line starting with CTEXT and replace IDC_STATIC with IDC_MidTextObj to make sure that the STATIC TEXT item uses my pre-created value.
ALSO, if you look carefully, you see that the next line defines another STATIC TEXT item (a new static text item I added to the window in the Dialog Editor). But this is LTEXT instead of CTEXT. Without peeking at this code as text, I would not have known that there are these two different types. Maybe LTEXT is what I was after. I will see what I find about this in the documentation.
ANSWER 4)
Not as a one-liner. See also the next section of my answer for details. But it can be done with multiple lines of code, calling methods to first query the current state of visibility of the object, then hide it if it is visible, or show it if it is hidden.
ANSWER 5)
NO, there is no way to do that in VC++. It works in other languages, but in C++ you have to call functions/methods. See answer from Mark Ransom at the bottom of a similar issue.

Concatenate String in resource file and pass it to menu item string (winapi) c++

I am writing a win32 application using winapi
and i want to concatenate a string in my resource file and give the stirng to my menuitem as the string it should show.
when i want to give it to a control it works like a charm, but when i want to
use it for the menuItem i get an error message. this might me because the preprocessor does not see the concatination as a string?
does anybody have a clue or idea what i could try?
there were simillar post i tried to follow - but it gives me the same result...
other posts on so:
Concatenate string and constant in resource file in C++ (MFC)
Concate define and string in resources
C/C++ Macro string concatenation
as i followed these answeres, i got "ID_ABOUT_STR" as my output instead of the value of it most of the times... and else i got the error...
i hope the question is clear and thank you in advance for the effort :)
.rc File:
IDR_MENU1 MENU
BEGIN
POPUP L"System"
BEGIN
MENUITEM ID_EXIT_STR, ID_SYSTEM_EXIT
MENUITEM SEPARATOR
MENUITEM ID_ABOUT_STR, ID_SYSTEM_ABOUT //here i want to give it the ID_ABOUT_STR which is in the resource file...
END
END
resource.h : VER_PRODUCTNAME_STR and the other one just contain strings aswell
#define ID_ABOUT_STR L"About" VER_PRODUCTNAME_STR L" " VER_FILE_DESCRIPTION_STR
This is the error i get:
Error RC2122 unknown menu subtype PRO-PRODUCITON C:\XXX.rc 195
Error RC2125 expected ID value for menu item PRO-PRODUCITON C:\XXX.rc 195
The problem is the L extension from my point of view. The code should compile without the L"..." prefix.
And as your links show, this macros work without problems in the RC compiler
#define CONCAT(a,b) a##b
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
As a sample this works for a caption in a dialog
CAPTION STRINGIZE(CONCAT(Concat,Title))
But they don't use the L"..." prefix

How to use preprocessor directives inside a MENU in MFC .rc file?

I want to be able to dynamically change code in my resource file depending on which version of my app is being ran. For example, I have an about menu. I would like the about menuitem to have a different description based on a preprocessor directive. The issue I have is I am able to add the code in. But when I edit the resource file and save it, the .aps file overwrites my preprocessor directives. How can I get around this? The code below is an example of what I would like to have in my resource script.
IDR_EXAMPLE_MENU MENU
BEGIN
/*
Other Menu items
*/
POPUP "&Help"
BEGIN
MENUITEM "&Help Topics", ID_HELP_FINDER
MENUITEM SEPARATOR
#ifdef TEST_APP
MENUITEM "&About TEST...", ID_APP_ABOUT
#else
MENUITEM "&About RELEASE...", ID_APP_ABOUT
#endif
END
END
If I am running the TEST version I would like it to display "About TEST" in the menuitem and if it the RELEASE version I would like it to display "About RELEASE"
How can I add code like this to my resource file without having the .aps file overwrite the preprocessor directives when saving the .rc file?
Edit: This explains how files are affected by resource editing.
It is also possible to have one resource like e menu twice inside your resource file.
Each resource can have a condition in its properties. And you can have a resource with the same name twice in your resources.
You may add the condition _DEBUG to the first resource. Just copy it and give the the condition _RELEASE. Rename it back to the same Id.
You can put your code in separate rc files and include them using the Compile-Time Directives field of the Set includes dialog. See Using Multiple Resource Files in the Same Project
If the resources are not changed frequently you can move them to the .rc2 file which is not modified by the Resource editor. And you can use pre-processor freely.
The other option is to create multiple .rc files (for example copy the original .rc file and remove the rest) and include them conditionally in the "Resource Includes.. > Compile-time directives" section which the Resource editors stores in the .rc file and repeats at the end of the .rc file as-is.
For example:
Create two .rc files like
ResourcesDebug.rc:
....
POPUP "&Help"
BEGIN
MENUITEM "&Help Topics", ID_HELP_FINDER
MENUITEM SEPARATOR
MENUITEM "&About TEST...", ID_APP_ABOUT
END
END
....
ResourcesRelease.rc:
....
POPUP "&Help"
BEGIN
MENUITEM "&Help Topics", ID_HELP_FINDER
MENUITEM SEPARATOR
MENUITEM "&About RELEASE...", ID_APP_ABOUT
END
END
....
You can add them to your repo, but need not to add them to the project. But if you add them to your project you have to exclude them from the compilation.
Compile-time directives (Resource view > Right click the .rc):
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#include "res\TestApp.rc2" // non-Microsoft Visual C++ edited resources
#ifdef TEST_APP
#include ResourcesDebug.rc
#else
#include ResourcesRelease.rc
#endif
....
Some more links:
Files Affected by Resource Editing
How to: Include Resources at Compile Time
You want to be able to use the resource editor of VS, but it only knows how to generate 1 kind of .rc output, and that is WITHOUT any of your #define values. You can't have it both ways. You can use compiler directives and edit the .rc (or .rc2) file by hand, or accept the output of VS.
A possibility may be to let you edit the file in VS using the resource editor, and then write a post-processing program that kind of understands the general content of your .RC and re-generate the "desired" .RC replacing the raw content with your compiler directives. It's do-able, but the trade-offs are very specific to your application.

How do I get a Resource ID edit in MFC editor to propagate to code?

I make a button in the resource editor in an MFC program.
I give it an ID.
I use the ID in code with CWnd *tLabel = GetDlgItem(IDC_CHANGETWO);
I am pleased.
I go back to editor
I change the ID
Code does not acknowledge new name, even with rebuild
I change some flag (tabstop)
Code still does not care
In order to get an ID name change to propagate to the code, I have to change the ID AND any other field in the same save. Only then does it realize it is dirty and update the resource table.
This is 100% reproducible on mine and my students' computers. This workaround has kept the class from stalling, but... what the heck is this?
Visual Studio Enterprise 2015
Version 14.0.23107.0 D14REL
If you change the name of a resource control it will not propagate that throughout your source code as you have already learned.
Ideally you need to use something like VisualAssist: http://www.wholetomato.com/
It allows you to rename your resource ID values
What you need to use is refactoring. If you open your resource file as a text file in the IDE (as opposed to the resource editor) and locate your control, you should be able to right-click it and choose Refactor (VA):
Then select Rename. It should preview the changes in the various source code files:
You can use the same procedure for renaming variables and method declarations.
While the answer given is good, it doesn't show what happens behind the scene when you update a resource ID.
All resource IDs go into one header: resource.h
This file is read by C++ compiler, as well as by resource compiler (the .RC file.)
Using resource editor, you just type an ID, and the resource-editor would simply create an entry in resource.h
This header looks like:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by MFCApplication1.rc
//
#define IDR_MAINFRAME 128
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_MFCAPPLICATION1_DIALOG 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 32771
#endif
#endif
So, when you add a new control on dialog (or any other form), and name it IDC_DOWNLOAD_NOW, and save the resource, this header will get updated like:
#define IDR_MAINFRAME 128
#define IDC_DOWNLOAD_NOW 1000
Also, internal variable (like _APS_NEXT_CONTROL_VALUE gets updated).
Well.. when you have same symbol in other dialog, VS will simply use the same macro with same value. You add another button on third dialog with same name, it doesn't modify resource.h either.
But... when you modify control in these 3 dialogs to name is like IDC_DOWNLOAD_LATER, only .RC and resource.h get updated. Old value, and old usages still exist. You wont get any compiler error (since macros are there!).
#define IDR_MAINFRAME 128
#define IDC_DOWNLOAD_NOW 1000
#define IDC_DOWNLOAD_LATER 1001
In another case, when you remove the button (from any of 3 dialog boxes), program will compile fine, but GetDlgItem, DDX_Control etc will fail at runtime (Since IDC_DOWNLOAD_NOW doesn't exist in current dialog!)
Now think what would happen if you mass rename the symbols using any tool - boom - all resources now have IDC_DOWNLOAD_LATER!
You should use Resource Symbols dialog to find what resource IDs are used by which dialog. From here you can rename and delete also.
Here is a second possible way to handle the specific issue of IDC_STATIC. Your question should be modified to include this.
I have started a temporary dialogue project and selected the default static text:
As you can see, it is labelled IDC_STATIC. I now directly change the ID value in the resource editor itself and hit the enter key:
Then I save it (this updates the resource.h file). Then, this is what we see if I use an application called ResOrg:
As you can see, the resource.h file is correct. It is at this point you now add your variables.
Interestingly, the IDE does not actually allow you to add variables to IDC_STATIC objects anyway. But suppose you have two if them:
You can still rename each one, save the file, re-build, and view your resource file:
As you can see, it is all still good. It is at this point that you can add variables and event handlers now. And it is in this context where VisualAssist would be used to rename variables/ID's used throughout your application.
I was not sure to edit my existing answer with this additional information. Perhaps that might be better?

Qt QIcon SVG different sizes

I am using the QIcon class of Qt to set the application icon of my apps.
My icons are SVG files, which load just fine.
QIcon appIcon;
QString iconPath = "share/icons/myapp.svg;
QFile iconFile(iconPath);
if (iconFile.exists()) {
appIcon.addFile(iconPath);
}
QApplication::setWindowIcon(appIcon);
My question is:
I want to have different icons for different pusposes.
For instance, I'd like to have different icons (i.e. sizes) for the title bar and for the actual icon, showed when pressing ALT+TAB.
I found the QSize parameter of addFile(), but then, the icon would stick to one certain size, which I don't know (because different window managers could have different title bar sizes).
How can I define an icon for the title bar and one for the rest (that's pretty much the short version of what I am asking)?
Kind regards,
mefiX
I normally use a separate PNG image (16x16 pixels, e.g. "./Icons/app_window.png") to set the title bar icon using the setWindowIcon() function in my mainwindow class constructor:
this->setWindowIcon(QIcon(QLatin1String(":/Images/Icons/app_window.png")));
For the rest icons you can use the following excellent freeware application:
http://www.icofx.ro/
It allows you to create both a "myapp.ico" file (for MS-Windows) and a "myapp.icns" file (for Mac OSX) and if you start from a 256x256 image it can automatically create all icon sizes for you!
For Mac OS/X you must put the following line in your "MyApp.pro" file:
ICON = Icons/myapp.icns
For MS-Windows you must put the following line in your "MyApp.pro" file:
win32::RC_FILE = myapp.rc
and you have also to create a "myapp.rc" file that look like this:
IDI_ICON1 ICON DISCARDABLE "./Icons/myapp.ico"
#include <windows.h>
#include "MyAppVersion.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR
VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
The #include "MyAppVersion.h" and the rest options is off-course optional but you can use it to define all the VER_xxx constants instead of putting them directly as a constant string like "MyAppName". The only important line for icon definition is the first one:
IDI_ICON1 ICON DISCARDABLE "./Icons/myapp.ico"
which implies that a file "MyApp.ico" resides in the folder ./Icons/
Note also that on MS-Windows if you modify your "myapp.ico" file, rebuild your project and run your application again, the icon is not always displayed right, due to the icon cache of windows-explorer.
Here is a link with various methods to clear/rebuild the windows-explorer icon cache:
Rebuild icon cache to fix incorrectly displayed icons
You can use one SVG-Icon in different position, it should be scaled when drawn. But the application icon (shown at ALT+TAB) is different, see the documentation here.
To learn how to convert SVG icons to the ico format, look here.