Win32 Cannot LoadImageW at runtime - windows

Trying to use Win32 API to load an icon for an application.
case WM_CREATE: {
auto hIcon = LoadImageW(NULL, L"C:\\icon.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if (hIcon) {
SendMessage(handle, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
} else {
auto lastError = GetLastError();
MessageBox(handle, L"Could not load icon!", L"ERROR", MB_OK | MB_ICONERROR);
}
}
What I get is the message box as above, with lastError being 0. The icon is located at the absolute path specified, and if the file is renamed such that the path is invalid last erorr code is 2 (file not found). Therefore, I assume the icon is found.
What I've tried:
Playing with relative paths.
Saving in different file formats, .png and .bmp, using Windows Paint, to avoid improper format errors.
Adding different flags, such as LR_LOADTRANSPARENT.
handle is NULL or GetModuleHandle(NULL)

The image must be an .ico file in some specific format. The one which worked correctly for me was exporting it from GIMP with 'Windows Icon' format selected. The icon was previously in the .ico format, it just wasn't right for some reason. Examples which load it from .bmp and .png did not work for me, that works only for bitmaps, which are not icons.
If the file is found, and the formats are not correct, there won't be anything in last error.

Related

QPixmap empty when loading it from an image

I have an app that loads an image in a QPixmap, which changes depending on the user's request.
Not all images have the same format, or the same size, some vertical and others horizontal.
I am using Qt5.14.2, with MinGW 7.3.0 32-bit and Qt Creator 4.11.1. in W10.
On a machine running W8.1 and the same version of Qt, MinGW and QtCreator have been working fine.
The first image loads perfectly, but if I change it, it already returns the empty QPixmap.
I have done different tests to be able to load the image, resizing the QPixmap (with fixed dimensions and with those of the image),
saving the QImage to a file and loading it from the file putting the PNG format, etc.
I have been able to check that the images are generated correctly, to rule out that it would be a problem when converting the data to QImage.
Any idea what is happening? I can't put the code because it's quite an extensive app, so I'll narrow it down to where the problem is
My_class.h:
QPixmap pixmap;
My_class.cpp:
int w=num_celdas_imagen_x*128;
int h=num_celdas_imagen_y*128;
unsigned char *data =(unsigned char *)malloc(w*h*3);
// filling data
QImage img = QImage((unsigned char *)data,w,h,QImage::Format_RGB888);
// At this point I have been able to check that the image is generated correctly
this->pixmap = QPixmap::fromImage(img);
// At this point the QPixmap is null (except with the first image, which loads fine)
Thanks

Win32 Toolbar Custom and Default icons on same bar

I realize win32 toolbar icon questions are common here, but none are relevant to my particular problem (most concern image lists, or associating with a bitmap handle).
I am trying to associate a toolbar button with an icon resource within my application. Since I am adding it to a toolbar that already has default images using TB_ADDBITMAP (new, open, save, etc), I cannot use an image list, as the article on MSDN says here:
The TB_SETIMAGELIST message cannot be combined with TB_ADDBITMAP. It also cannot be used with toolbars created with CreateToolbarEx, which calls TB_ADDBITMAP internally. When you create a toolbar with CreateToolbarEx or use TB_ADDBITMAP to add images, the toolbar manages the image list internally. Attempting to modify it with TB_SETIMAGELIST has unpredictable consequences.
MSDN says I should be able to use a resource directly with TB_ADDBITMAP, under the TBADDBITMAP::nID field:
If hInst is NULL, set this member to the bitmap handle of the bitmap with the button images. Otherwise, set it to the resource identifier of the bitmap with the button images.
The VS2008 resource editor shows a single 16x16 icon resource with the id IDI_ARROWLEFT. (I had a screenshot, but since I do not have enough "reputation" to post images you'll have to take my word for it)
This is clearly a valid icon as the following code makes the icon appear on the titlebar of the main window:
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ARROWLEFT));
The problem is the resource icon is not appearing on the toolbar button within the window. Below is the sample code that is loading the resource and applying it to the toolbar button:
void populateToolbarTest()
{
int index = -1;
TBADDBITMAP tbab;
TBBUTTON tbb;
ZeroMemory(&tbab, sizeof(TBADDBITMAP));
ZeroMemory(&tbb, sizeof(TBBUTTON));
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
tbab.hInst = hInst;
tbab.nID = IDI_ARROWLEFT;
// SendMessage returns 0 when testing
index = SendMessage(hWndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab);
if (index == -1) return;
tbb.iBitmap = index;
tbb.fsState = TBSTATE_ENABLED;
tbb.fsStyle = TBSTYLE_BUTTON;
// result is set to 1 when testing
LRESULT result = SendMessage(hWndToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbb);
}
This code successfully produces a button. However, there is no icon displayed, unlike with the defaults that I used in IDB_STD_SMALL_COLOR
I finally got it working. Turns out, it had nothing to do with the code.
Microsoft is EXTREMELY picky about the EXACT format of the image being referenced. It you use TB_ADDBITMAP with a custom image, it MUST be 256 colors, it MUST have the MS-Specific index format, and the only color I've gotten to register as transparent is black. I spent an hour in Photoshop messing with different formats and colors before figuring this out.
The clue was the CreateMappedBitmap function in the example on MSDN. The page on CreateMappedBitmap had this statement:
This function is fully supported only for images with color maps; that is, images with 256 or fewer colors.
What it doesn't mention is that this is true regardless of whether you use this function or not. I have tried each scenario with and without this helper function, as well as tried every other 256-color BMP index format. Some other formats managed to show up, but they were mangled.
Theoretically, you can use the CreateMappedBitmap COLORMAP to specify a transparency color other than black, but I'm not familiar enough with the "6 level RGB" format to know how to specify an exact color.
(ref: http://en.wikipedia.org/wiki/List_of_software_palettes#6_level_RGB)
Unless you're mixing custom icons with default ones, I would recommend sticking with TB_SETIMAGELIST. From what I've read, it's much more flexible (for example, it accepts more than 256 colors.)
(ref: Win32 Toolbars and 24bit Images)

Using Windows Vista/7 themes with g++

I have done an application with g++ using pure winapi, but every control looks very old. How can I use the new nice themes 7 and Vista offer? Everything I have read so far says that I must include an XML file saying explicitly that I want those themes, but I don't think that is possible with g++ . So, what should I do?
You do need to include a manifest to your project.
This is just a simple xml file that you add to your project as if it were a .cpp or .h file.
It will enable the nice visual styles, but you're not there yet!
The font is still the ms shell dlg which is not all that amazing.
To "extract" the standard font, you use the GetStockObject function with the DEFAULT_GUI_FONT flag
HFONT font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
To calculate the new dialog units for this font you can use this little snippet.
LONG units = GetDialogBaseUnits();
HDC hdc = GetDC(NULL);
SIZE size;
TEXTMETRIC tm;
HFONT font = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
SelectObject(dc,font);
GetTextMetrics(dc,&tm);
GetTextExtentPoint32(hdc,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",52,&size);
float avgWidth = (size.cx/26+1)/2;
float avgHeight = (WORD)tm.tmHeight;
float dialogUnitWidth = 2*(avgWidth/LOWORD(units));
float dialogUnitHeight = 2*(avgHeight/HIWORD(units));
dialogUnitWidth and dialogUnitHeight now contain the dialog units in pixels.
See this article for more information.
I don't know g++. But if the result of this environment/language you get is a simple EXE and the controls that are used are standard Windows controls adding a manifest to the exe will do the job.
The easiest way is to create a valid manifest with the complete Name of the exe and add .manifest to the Name. (i.e. foo.exe.manifest)

How to reference hello.bmp inside my .app?

I'm following the lazyfoo tutorials on SDL and I'm on lesson 01, getting an image on the screen, but SDL is giving me "Couldn't load hello.bmp", and I can't figure out why.
I'm using OS X, Xcode 3.2, and the latest version of SDL from their website.
I suspect it has something to do with not loading the hello.bmp image into Xcode correctly, but I've followed the tutorial and further Googling has produced no helpful results. Does anyone know how to troubleshoot this further?
Edit: It seems it has to do with relative paths. Still not sure what part is wrong though...
Edit: I've figured out that by going to Project -> Edit Active Executable and changing Set The Working Directory to 'Project Directory' works for now, but I don't understand why it won't load the hello.bmp in the .app itself. What am I missing?
Edit: Below is the source code for the lazyfoo lesson 01, included as per request. This is the code I'm using character for character, if you need any information about my XCode (Version 3.2), let me know.
/*This source code copyrighted by Lazy Foo' Productions (2004-2012)
and may not be redestributed without written permission.*/
//Include SDL functions and datatypes
#include "SDL/SDL.h"
int main( int argc, char* args[] )
{
//The images
SDL_Surface* hello = NULL;
SDL_Surface* screen = NULL;
//Start SDL
SDL_Init( SDL_INIT_EVERYTHING );
//Set up screen
screen = SDL_SetVideoMode( 640, 480, 32, SDL_SWSURFACE );
//Load image
hello = SDL_LoadBMP( "3.app/Contents/Resources/hello.bmp" );
//Apply image to screen
SDL_BlitSurface( hello, NULL, screen, NULL );
//Update Screen
SDL_Flip( screen );
//Pause
SDL_Delay( 2000 );
//Free the loaded image
SDL_FreeSurface( hello );
//Quit SDL
SDL_Quit();
return 0;
}
This is incorrect:
SDL_LoadBMP( "3.app/Contents/Resources/hello.bmp" );
You should get the path for a resource in your application's bundle by calling [[NSBundle mainBundle] pathForResource:#"hello" ofType:#"bmp"], which will return an NSString object with the absolute path of the file corresponding to that resource.
I've found that by replacing "hello.bmp" in the lesson01 source code with "X.app/Contents/Resources/hello.bmp" where X is the name of your XCode project, this correctly references the app that is built even if the .app is copied to the desktop and ran there.
Also, don't forget to add hello.bmp to the XCode project.

Images for file extensions

I want the small images of different file formats (docx,ppt,txt etc.) to display along with the file names of corresponding type.
Any link to get these images?
TIA.
If you want to display a file list with the associated icons showing net to the file name in your program, you can use the SHCreateFileExtractIcon Function from the shell extension of Windows. It extracts the associated icon for a given file.
HRESULT SHCreateFileExtractIcon(
LPCTSTR pszFile,
DWORD dwFileAttributes,
REFIID riid,
void **ppv
If you want to have the exact icons that are associated with files at any time, this is the way to go. You could always store these icons you obtain to disc to come up with your own set of icons.

Resources