I started making a simple c++ Win32 program. I was simply trying to load an Image into a window, but it didn't really work. I was debugging for some time, and I know that the problem is that my LoadImageW() function returns null. Code:
void loadImages() {
hPic1 = (HBITMAP)LoadImageW(NULL, L"pic.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (hPic1== NULL) {
MessageBox(NULL, L"Error", L"LoadImage error", MB_OK);
}
}
The .bmp file is in the same directory with the .cpp file, and I even tried with the whole path but it didn't work. I get no errors and the main window loads correctly, but the image doesn't display and the message box appears. The loadImages() function gets called at WM_CREATE of the window. The SendMessageW() function looks like this:
SendMessageW(hImageWindow, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hPic1);
Any help is appreciated, and have a nice day!
After calling LoadImageW or any win api function that leads to unexpected result! check documentation in MADN especially "Remarks" section!
Based on documentation may be it is good to call GetLastError()! By checking error code you find the problem, such as "file not found", access privilege error and etc.
You can find description of each error code returned by GetLastError() in page https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes or check by visual studio IDE in Tools-> Error lookup menu!
Related
As the title says, I'm trying to write a simple window program, but when I try to change the icon of my TreeView, it goes wrong. I'm pretty sure my icon was loaded because I did this:
HICON hIcon;
//hinst is my global variable
hIcon = LoadIcon(hinst,(char*)IDI_ICON_MAIN);
if (hIcon == NULL)
{
MessageBox(NULL, "LoadIcon failed", "error", MB_OK);
}
It works fine then I use ImageList_ReplaceIcon():
if (ImageList_ReplaceIcon(iml, 3, hIcon) == -1)
{
MessageBox(NULL, "replace icon failed", "error", MB_OK);
}
TreeView_SetImageList(hwndTV, iml, TVSIL_STATE);
First, I thought, maybe it's because I gave the wrong ILC_COLOR in ImageList_Create(), then I rechecked the bit of my icon then reset the parameter, but it's still not working.
Can anyone give me some clue of what is wrong? I already checked with Google and read the docs mutiple times, perhaps I missed something?
UPDATE [2022/05/31]
Here is my TreeView:
I'm tring to change my icon to the red circle.
I can see my icon now, thanks. I appreciate those who gave me advice.
ReplaceIcon() can only be used when I have already added an icon into it. If there's no icon in it then the only condition I can use is to set the index to -1, so that the ReplaceIcon() can add the icon for me.
I'm not familiar with MFC but currently I must continue a project that was written in MFC. Now I'm having trouble with the following line when debugging
m_hIcon = AfxGetApp()->LoadIcon (IDR_MAINFRAME);
It always stops after the error "Assertion Failed: at afxwin1.inl". If I put a breakpoint there I saw a NULL icon handle. I tried running in release mode and it worked just fine although the handle is still NULL. I've read this question but my program is not a static library. It's a program that use a dll to connect to a CAN bus device. And the resource IDR_MAINFRAME is already in the project. It contains the default MFC icons. How can I solve this problem?
I've tried debugging and see that pModuleState changes between the first load program name call and the second load icon call. The first call returns successfully because pModuleState points to an object that has valid handle. But in the icon load call, pModuleState points to some object contains NULL handle. I also tried putting AFX_MANAGE_STATE(AfxGetStaticModuleState( )); right above the LoadIcon() call but the problem still arises
I've known the cause of this problem
UINT __cdecl RunCPRead(LPVOID pParam)
{
CMyDlg *thisclass = (CMyDlg *)pParam;
while (thisclass->m_Start)
{
thisclass->GetData();
}
return 0;
}
AfxBeginThread(&RunCPRead, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
After the GetData() call in RunCPRead, the control flows directly to CMyDlg's contructor although there's no object being created or copied
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
and then fails at the assignment to m_hIcon with the error "access violation while reading". I've seen the disassembly, it was the line mov dword ptr [esi+90h], eax and it's inherently a write to memory.
I don't know why. How can I solve this?
The MFC code need the correct module handle to load the resource.
Please try to read Afx*G/S*etResourceHandle.
By default MFC uses the resource handle of the main application, not of the DLL. If you are making the call in the DLL then add this line at the start of the exported DLL function:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
There is more information about this here:
http://msdn.microsoft.com/en-us/library/ba9d5yh5(v=vs.110).aspx
Assertion Errors in MFC usually happens when wrong settings are set.
go to project settings > linker > System and change subsystem to (/SUBSYSTEM:WINDOWS) this solution solved my own problem.
When I use ATL in MFC Application(Don't ask me why, just because I like), sometimes I got the error code: E_FAIL. However, it's almost useless for me to locate the specific reason.
I have googled so many times, but found nothing related. I thought there should be something like try{} catch{} in ATL.
Here's some sample code:
CAxWindow m_wndView; // ActiveX host window class.
CComPtr<IWMPPlayer> m_spWMPPlayer; // Smart pointer to IWMPPlayer interface.
AtlAxWinInit();
CComPtr<IAxWinHostWindow> spHost;
HRESULT hr;
CRect rcClient;
GetClientRect(&rcClient);
m_wndView.Create(m_hWnd, rcClient, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
//when I switch to Static Link to ATL from Dynamic Link to ATL, I always get E_FAIL
hr = m_wndView.QueryHost(&spHost);
Anyone can help me?
The error code is entirely function specific. Think of piece of code [on the other side] that does return E_FAIL; What additional detail one can get from it? Chances are high you have no detail at all.
Sometimes you can obtain additional information using GetErrorInfo API which in your case - having your code snippet in mind - is unlikely.
The best you can do is to step inside to reach as close as possible to the origin of the code in order to tell where it comes from.
Use the _com_error class.
Construct an object of this class by passing in the HRESULT value and then use its WCode or ErrorMessage methods to get the error code mapped to the HRESULT value.
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).
I am now working on a some sort of a game engine and I had an idea to put everything engine-related into a static library and then link it to my actual problem.
Right now I achieved it and actually link that library and every functions seem to work fine, except those, which are windows-related.
I have a chunk of code in my library that looks like this:
hWnd = CreateWindow(className, "Name", WS_OVERLAPPED | WS_CAPTION | WS_EX_TOPMOST,
0, 0,
800, 600,
NULL, NULL, GetModuleHandle(NULL), this);
if (hWnd) {
ShowWindow(hWnd, SW_NORMAL);
UpdateWindow(hWnd);
} else {
MessageBox(NULL, "Internal program error", "Error", MB_OK | MB_ICONERROR);
return;
}
When this code was not in the library, but in the actual project, it worked fine, created the window and everything was ok. Right now (when I'm linking to my library that contains this code) CreateWindow(...) call returns NULL and GetLastError() returns "Operation succesfully completed" (wtf?).
Could anybody help me with this? Is it possible to create a window and display it using a static library call and why could my code fail?
Thank you.
Ah, maybe you've run into this problem described in an MSDN blog:
If you're writing a static library, you may have need to access the HINSTANCE of the module that you have been linked into. You could require that the module that links you in pass the HINSTANCE to a special initialization function, but odds are that people will forget to do this.
If you are using a Microsoft linker, you can take advantage of a pseudovariable which the linker provides.
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
The pseudovariable __ImageBase represents the DOS header of the module, which happens to be what a Win32 module begins with. In other words, it's the base address of the module. And the module base address is the same as its HINSTANCE.
So there's your HINSTANCE.
So, instead of passing GetModuleHandle(NULL) to CreateWindow, try ((HINSTANCE)&__ImageBase) (make sure it is declared as shown in the blog first).
Edit:
From the comments in that blog entry, one mentions the use of GetModuleHandleEx(), perhaps this is a more Compiler/Linker-agnostic approach.