LoadImageW returns NULL

This is a simple windows application made with windows.h.
I wanted to add an ìmage to it, but the LoadImageW function returns NULL and the image doesn't show up. I added a condition that prints NULL if the value of hLogoImage is NULL, and it holds. Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <windows.h>    
#include <tchar.h>
#include <iostream>

#define FILE_MENU_NEW 1  
#define FILE_MENU_OPEN 2 
#define FILE_MENU_EXIT 3 
#define CHANGE_TITLE 4


LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); 

void AddMenus(HWND);

void AddControls(HWND);

void LoadImages();

HMENU hmenu;

HBITMAP hLogoImage;

HWND hedit;

HWND hLogo;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow) { 
	WNDCLASSW wc = {0};    						
	
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;   
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);    
	wc.hInstance = hInst;			           
	wc.lpszClassName = L"WinClass";            
	wc.lpfnWndProc = WinProc;                  
	
	if(!RegisterClassW(&wc)) {  			
		return -1;			    				
	}
	 
	CreateWindowW(L"WinClass", L"Iea boi", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, NULL, NULL);

	MSG msg = {0};

	while( GetMessage(&msg, NULL, NULL, NULL))

	{ 
		TranslateMessage(&msg);
		DispatchMessage(&msg);		
	}

	
	return 0;
	
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {	
	switch(msg)	{
		
	case WM_COMMAND:	                                 
		
		switch(wp){	                                  	  
		case FILE_MENU_EXIT:               				  
			DestroyWindow(hwnd);						  
			break;
		case FILE_MENU_NEW:							      
			MessageBox(hwnd, "HIII", "New", MB_OK);
		        MessageBeep(MB_ICONQUESTION);               	
			break;
		case CHANGE_TITLE:								  
			wchar_t text[100];							  
			GetWindowTextW(hedit, text, 100);			  
			SetWindowTextW(hwnd, text);					  
			break;
		}
		break;
			
	case WM_CREATE:    									  
		LoadImages();									  
		AddMenus(hwnd); 								  
		AddControls(hwnd); 								  
		break;		
		
	case WM_DESTROY:	    							  
		PostQuitMessage(0); 							  
		break;
		
	default: 	                                  		  
		return DefWindowProcW(hwnd, msg, wp, lp);		
	}	
}


void AddMenus(HWND hwnd) {
	hmenu = CreateMenu();           					  
	HMENU hFileMenu = CreateMenu(); 					  
	HMENU hSubMenu = CreateMenu();  					  
	
	AppendMenu(hSubMenu, MF_STRING, NULL, "SubMenu Item");       
	
	AppendMenu(hFileMenu, MF_STRING, FILE_MENU_NEW, "New");  			 
	AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, "Open SubMenu"); 
	AppendMenu(hFileMenu, MF_SEPARATOR, NULL, NULL);                     
	AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, "Exit");            
	
	AppendMenu(hmenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");            
	AppendMenu(hmenu, MF_STRING, NULL, "Help");                          

	SetMenu(hwnd, hmenu);                                                
}

void AddControls(HWND hwnd){
	 
	CreateWindowW(L"Static", L"Inserisci testo: ", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_LEFT, 200, 100, 100, 25, hwnd, NULL, NULL, NULL);


	hedit = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_CHILD | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL , 200, 130, 100, 50, hwnd, NULL, NULL, NULL);

	//definisce un bottone, nella finestra iniziale, con la funzione CHANGE_TITLE
	CreateWindowW(L"Button", L"Change Title", WS_VISIBLE | WS_CHILD, 200, 185, 100, 25, hwnd, (HMENU)CHANGE_TITLE, NULL, NULL);

	
	hLogo = CreateWindowW(L"Static", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 350, 60, 100, 100, hwnd, NULL, NULL, NULL);

	
	SendMessageW(hLogo, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hLogoImage);
}

void LoadImages(){
	
	hLogoImage = (HBITMAP)LoadImageW(NULL, L"C:/Users/Vitiello/Desktop/PEPPE/PROGRAMMAZIONE/C++/WINAPI/logo.bmp", IMAGE_BITMAP, 100, 100, LR_LOADFROMFILE);
	if(hLogoImage == NULL){
		std::cout << "NULL";
	}
}
Last edited on
Add getlastError call after LoadImageW.

https://msdn.microsoft.com/en-gb/d852e148-985c-416f-a5a7-27b6914b45d4

You can use the value to determine what went wrong.
I copied from docs.microsoft.com a code to get the last error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void ErrorExit(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}


I added this immediately after the LoadImageW function:

1
2
if(!GetProcessId(NULL))
        ErrorExit(LPTSTR(TEXT("GetProcessId")));


The output i got was:

GetProcessId failed with error 6: Invalid handle.
Now what should I do?
Last edited on
closed account (z05DSL3A)
I have had a bit of a play with your WinProc() so a bitmap is loaded and painted (test.bmp in c:\data\ )...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
LRESULT CALLBACK WinProc (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {

    static HBITMAP bmpSource = NULL;
    static HDC hdcSource = NULL;

    PAINTSTRUCT ps;
    HDC hdcDestination;

    switch (msg) {

    case WM_COMMAND:

        switch (wp) {
        case FILE_MENU_EXIT:
            DestroyWindow (hwnd);
            break;
        case FILE_MENU_NEW:
            MessageBox (hwnd, L"HIII", L"New", MB_OK);
            MessageBeep (MB_ICONQUESTION);
            break;
        case CHANGE_TITLE:
            wchar_t text[100];
            GetWindowTextW (hedit, text, 100);
            SetWindowTextW (hwnd, text);
            break;
        }
        break;

    case WM_CREATE:
        bmpSource = (HBITMAP) LoadImageW (NULL, L"c:\\data\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        hdcSource = CreateCompatibleDC (GetDC (0));
        SelectObject (hdcSource, bmpSource);
        AddMenus (hwnd);
        AddControls (hwnd);
        break;

    case WM_PAINT:
        hdcDestination = BeginPaint (hwnd, &ps);
        BitBlt (hdcDestination, 0, 0, 500, 500, hdcSource, 0, 0, SRCCOPY);
        EndPaint (hwnd, &ps);
        break;
     
    case WM_DESTROY:
        PostQuitMessage (0);
        break;

    default:
        return DefWindowProcW (hwnd, msg, wp, lp);
    }
}

This is only a quick edit not best practice or designed to fit in with the rest of your code, I'll leave that to you...
I tried your code, and I got 4 errors

C:\Users\Vitiello\AppData\Local\Temp\ccTAn9sJ.o	BASE.cpp:(.text+0x2c5): undefined reference to `__imp_CreateCompatibleDC'

C:\Users\Vitiello\AppData\Local\Temp\ccTAn9sJ.o	BASE.cpp:(.text+0x2e6): undefined reference to `__imp_SelectObject'

C:\Users\Vitiello\AppData\Local\Temp\ccTAn9sJ.o	BASE.cpp:(.text+0x371): undefined reference to `__imp_BitBlt'

C:\Users\Vitiello\Desktop\PEPPE\PROGRAMMAZIONE\C++\WINAPI\BASE\collect2.exe	[Error] ld returned 1 exit status



I followed the path inn the last error, and i don't have any file called "collect2.exe" in the BASE folder

I think the first three appeared because I need to include another library, given that the error is in the reference

For the last error, I've only seen it when i tried to compile a program that was in execution, but this isn't the case
Last edited on
closed account (z05DSL3A)
Do you link to gdi32.lib? (I think that is the one you need)

Topic archived. No new replies allowed.