Loading an icon in Windows program - c++

I'm trying to set a custom icon into my program but nothing happens.
I created an icon using this tool.
I created a resource file with contents:
MYICON1 ICON "glider.ico"
I added the resource file into my Visual Studio 2013 project and set its type to "Resource Compiler". Type "Resource" doesn't work ("invalid or corrupt file: cannot read at 0x1A")
I load the icon with the following code when creating a window:
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( MYICON1 ) ); // MYICON1 is defined in Resource.h as 101.

Just to make sure that I have correctly understood your question…Everything compiles fine when you set the type of your resource file to "Resource Compiler", right? That is the correct setting, leave it there. The other stuff is for .NET applications.
So the problem is just that you aren't seeing the icon? What size icon did you create in the editor? The LoadIcon function is extremely old and can only load icons with the default size, generally 32x32. If you want to load icons with a different size, you will need to use the LoadImage function instead. Over 99% of the time, that's the function you should call to load icons. I haven't used LoadIcon in years.
HICON hIcon = static_cast<HICON>(::LoadImage(hInstance,
MAKEINTRESOURCE(MYICON1),
IMAGE_ICON,
48, 48, // or whatever size icon you want to load
LR_DEFAULTCOLOR);
Like Retired Ninja suggests in his comment, be sure to test the return values of functions when the code doesn't work as expected. For example, test whether hIcon is NULL. If so, the LoadImage function failed, and you need to figure out why. Most likely, the parameters you passed were incorrect. Either there is no resource with that ID in your application module, or there is no icon with the corresponding size in the icon file.
Another tip for debugging purposes is to use one of the built-in system icons. If you can see that icon, you know everything is working correctly, and you can start swapping things out to load your custom icon. For example:
HICON hIcon = static_cast<HICON>(::LoadImage(NULL,
MAKEINTRESOURCE(IDI_WARNING),
IMAGE_ICON,
0, 0,
LR_DEFAULTCOLOR | LR_SHARED | LR_DEFAULTSIZE));
That should show the standard warning icon, like the one you see in a message box. If that works, but loading your own icon doesn't work, the problem is very likely to be with the .ico file that you created.

You can set your icon resource like this and use Load Icon' with w c ex h Icon and w c ex h Icon Sm. It sets the project output icon and program icon at the same time.
'IDI_MAIN_ICON ICON "cellphone.ico"
'Load Icon( h Instance, MAKEINTRESOURCE(IDI_MAIN_ICON));'

Related

How do I implement this code into a dialog type resource file?

// Epvolume.rc -- Resource script
#include "resource.h"
#include "windows.h"
#include "commctrl.h"
//
// Dialog box
//
VOLUMECONTROL DIALOGEX 0, 0, 160, 60
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | DS_SETFONT
CAPTION "Audio Endpoint Volume"
FONT 8, "Arial Rounded MT Bold", 400, 0, 0x0
BEGIN
LTEXT "Min",IDC_STATIC_MINVOL,10,10,20,12
RTEXT "Max",IDC_STATIC_MAXVOL,130,10,20,12
CONTROL "",IDC_SLIDER_VOLUME,"msctls_trackbar32",
TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,10,20,140,12
CONTROL "Mute",IDC_CHECK_MUTE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,20,40,70,12
END
I don't know a thing about resource files, I tried to make it a dialog resource type but I don't quite know how to enter this code into that dialog file because I don't really know how to work it. Just to clear things up, when I make a new dialog file it gives me a blank dialog, which I don't know how to edit, maybe I'm doing something wrong? I don't know where to put the code
You need to open the resource file as text rather than with the designer. In solution explorer select the resource script file and hit ctrl+alt+0. You can then cut-and-paste text as usual.
Most of the time when simply laying out a new dialog it is easier to use the designer but editting it as text is much easier when you have existing resources you want to bring into a project.
Note that you will also need to edit resources.h to add the various control symbol names (for example IDC_SLIDER_VOLUME) as well as modifying _APS_NEXT_CONTROL_VALUE to be the next unused value.

How does the MFC PropertyGrid control work in the dialog editor in visual studio?

In the visual studio dialog editor i can add a MFC Property Grid control to the dailog. How can i customize its content, and set options like allowing the user to edit the contents of it when the program using it is running, or how i can change the contents of it using c++?
When i add something like a button or and edit control it displays on the dailog box when the program is running, while when i add a MFC Property Grid the dailog isnt even being displayed.
Here is a picture of the visual studio dialog editor and a MFC property control grid in the middle of the dailog with contents i dont know how to change.
Simple tutorial of CMFCPropertyGridCtrl:
1.Create a dialog-based MFC project, drag a CMFCPropertyGridCtrl into it, and adjust the size. Then change the ID for the control to IDC_MFCPROPERTYGRID_TEST, and use Add Varible to add a variable m_propertyGrid to the control. Change the setting of Notify to True.
Description Rows Count refers to the number of rows in the description section below.
Enable Description Area indicates whether to enable the following description function.
Enable Header indicates whether to start the header.
Mark Modified Properties indicates whether to highlight the changes.
2.Set interface
Add the following code in OnInitDialog()
HDITEM item;
item.cxy=120;
item.mask=HDI_WIDTH;
m_propertyGrid.GetHeaderCtrl().SetItem(0, new HDITEM(item));
Add content
Add the following code in OnInitDialog()
CMFCPropertyGridProperty* pProp2 = new CMFCPropertyGridProperty(
_T("choose"),
_T("select"),
_T(""));
pProp2->AddOption(_T("1"));
pProp2->AddOption(_T("2"));
pProp2->AddOption(_T("3"));
pProp2->AllowEdit(FALSE); //Editing of options is not allowed
m_propertyGrid.AddProperty(pProp2);
The three parameters passed in when calling the constructor are item name, default options and description text.
Also, you could add drop-down menu:
CMFCPropertyGridProperty* pProp2 = new CMFCPropertyGridProperty(
_T("choose"),
_T("select"),
_T(""));
pProp2->AddOption(_T("1"));
pProp2->AddOption(_T("2"));
pProp2->AddOption(_T("3"));
pProp2->AllowEdit(FALSE); //Editing of options is not allowed
m_propertyGrid.AddProperty(pProp2);
In addition, there are three similar projects:
CMFCPropertyGridColorProperty * pProp3 = new CMFCPropertyGridColorProperty(
_T("colour"), RGB(0, 111, 200));
m_propertyGrid.AddProperty(pProp3);
CMFCPropertyGridFileProperty * pProp4 = new CMFCPropertyGridFileProperty(
_T("open file"), TRUE, _T("D:\\test.txt"));
m_propertyGrid.AddProperty(pProp4);
LOGFONT font = { NULL };
CMFCPropertyGridFontProperty * pProp5 = new CMFCPropertyGridFontProperty(
_T("select font"), font);
m_propertyGrid.AddProperty(pProp5);
Finally, This is the final program running interface:

Extract Icon From An Executable - ExtractAssociatedIcon

I am trying to extract the icon from an executable which is associated with html files. On my system, html files are associated with Chrome.
My code is:
std::unique_ptr<wxFileType> c_type(wxTheMimeTypesManager->GetFileTypeFromExtension("html"));
if (c_type)
{
wxIconLocation location;
c_type->GetIcon(&location);
WORD index = 0;
HICON hicon = ExtractAssociatedIcon(wxGetInstance(), (LPWSTR)location.GetFileName().ToStdString().c_str(), &index);
wxIcon icon;
bool res=icon.CreateFromHICON(WXHICON (hicon));
wxBitmap bmp;
bmp.CopyFromIcon(icon);
if(bmp.IsOk())
MenuItem->SetBitmap(bmp);
}
The icon will be associated with a menu item and when the menu pops up:
It is seen that rather than the Chrome icon, I am seeing a different one. I tried it with different file extensions (xlsx, docx, rtf...) and every time I am getting the same icon.
What am I missing?
Thanks in advance.
By the way, I am using wxWidgets 3.1.3 on Windows 10.

Create window without title bar

I am trying to create a simple panel for Openbox in Arch Linux using c++, but I cannot figure out how to remove the title bar from a window.
I am creating the window with XCreateWindow(...), and that gives a window with the correct size, but it contains a title bar, and the window also opens in the top-left corner of the screen, no matter what offset coordinates I specify.
I read here that both of these problems are probably caused by the window manager (Openbox), which overrides the window attributes I specified in XCreateWindow(..., &window_attributes). This could be solved by adding window_attributes.override_redirect = True;, although this does not seem to do anything for me. When I try this I get the exact same window as before. (I did compile the file after this change.)
Also I read into the code of Tint2 (link), which is another panel for Openbox. They create a window using the following code:
XSetWindowAttributes att = { .colormap=server.colormap, .background_pixel=0, .border_pixel=0 };
p->main_win = XCreateWindow(server.dsp, server.root_win, p->posx, p->posy, p->area.width, p->area.height, 0, server.depth, InputOutput, server.visual, mask, &att);
I don't see an override_redirect anywhere in their code, so I'm not sure how they are removing the title bar.
As additional information, I thought it would be worth mentioning how I'm executing the script:
/* The c++ file is saved as 'panel.cpp' */
$ gcc panel.cpp -lX11 -o panel
$ ./panel
Also, I am running Arch Linux through VirtualBox with Windows 8 as host. I'm not sure if this changes anything, but it won't hurt to mention.
Since I found the solution, I figured I'd post the solution here if anyone else needs it.
As #JoachimPileborg mentioned, I needed to alter the Openbox settings in ~/.config/openbox/rc.xml. Inside the <applications> tag, I added the following code:
<application class="*">
<decor>no</decor>
<position force="no"></position>
</application>
The class="*" means that all applications will follow these rules, you could fill in the class name of the application instead. The <decor>no</decor> removes the title bar, and <position force="no"></position> ensures that my own script is able to handle the positioning. You could also add another <application> tag after this one to make exceptions to this rule.
Also, the window_attributes.override_redirect = True; is not needed anymore.
A more correct way is to use the Extended Window Manager Hints.
The idea is that you don't tell the window manager how to decorate or not your window, you just indicate the window type with _NET_WM_WINDOW_TYPE :
Atom window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
long value = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK", False);
XChangeProperty(display, your_window, window_type,
XA_ATOM, 32, PropModeReplace, (unsigned char *) &value,1 );
"Dock" is the type for panels and taskbar. Usually they are undecorated and appear on all desktops. As written on the documentation, previously the _MOTIF_WM_HINTS property was used to define the appearance and decorations of the window. Window managers still support it, but _NET_WM_WINDOW_TYPE is prefered as it describe the function and let the window manager (and user) decide on the appearance and behavior of that type of window.
Another interesting property for a panel is _NET_WM_STRUT_PARTIAL, to "reserve" space.

Windows LoadMenu error: "The specified resource name cannot be found in the image file."

I'm writing a program that, among other things, needs to display a context menu on right-click. I'm trapping WM_NOTIFY, the identifier of the control being clicked on, and NM_RCLICK. That all works great.
The problem comes in when I'm processing that right-click:
case NM_RCLICK:
{
HMENU Popup = LoadMenu(0, MAKEINTRESOURCE(IDR_NED_MENU));
if ( !Popup ) {
DWORD err = GetLastError();
char* buf;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, err, 0, buf, 1<<19, 0);
_ERROR("LoadMenu(0, MAKEINTRESOURCE(IDR_NED_MENU)); Error '%s' thrown; no menu loaded.", buf);
delete [] buf;
}
Popup = GetSubMenu(Popup, 0);
CheckMenuItem(Popup, 1, MF_CHECKED|MF_BYPOSITION);
POINT Point;
GetCursorPos(&Point);
switch (TrackPopupMenu(Popup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD, Point.x, Point.y, 0, GetActiveWindow(), NULL)) {
// ...
Primarily, LoadMenu(0, MAKEINTRESOURCE(IDR_NED_MENU)); is returning NULL, and I'm getting an error message that states that "The specified resource name cannot be found in the image file."
Now, IDR_NED_MENU is the ID of a menu I have in the .rc file, and I've included the corresponding .rc.h file in this .cpp file. The actual dialog window IDs contained in the same .rc file work perfectly. This code is further copied and pasted from another project where the LoadMenu call worked perfectly: I did recreate the IDR_NED_MENU from scratch, though, and the IDs are somewhat different (but they do match between the .rc file and the .cpp file that has the code snippet I've pasted here); originally I'd accidentally created the menu in a separate .rc file so I sought to rectify that here. I noticed that in Visual Studio's Resource View, the dialogs are contained in the Dialog folder, while this is contained in the Menu folder (sensible), but I'm not sure what, if any, difference that makes.
Why would I be getting this error? Why can't it find IDR_NED_MENU?
I'm using Visual Studio 2010, and this is not an MFC project. I'm not sure what, if any, other relevant details I should include; let me know in comments and I'll edit-update.
Thanks.
The first parameter to LoadMenu must be a handle to your executable image where the resource resides. The handle is the first HINSTANCE that you get in WinMain. Alternatively you can obtain it by a call to GetModuleHandle(0).