How to get detail error info from E_FAIL? - c++

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.

Related

LoadImageW returns null c++ win32

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!

Directshow render filter crashes only in release mode

I've written a custom renderer filter to push video frames to system memory and later to OpenGL. It's not in a DLL and I don't register it, but instead use it like this page describes in the first paragraph. This works fine in the Debug mode, but in Release it starts crashing. I'm doing the following to initialize the graph:
HRESULT hr;
CoInitialize(0);
CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&graph);
graph->QueryInterface(IID_IMediaControl, (void**)&mediaControl);
graph->QueryInterface(IID_IMediaSeeking, (void**)&mediaSeeking);
grabber = new textureGrabber(0, &hr);
grabber->AddRef(); // crash here
grabber->setTexture(&texture);
grabber->QueryInterface(IID_IBaseFilter, (void**)&base);
graph->AddFilter(base, L"OpenGL texture video filter");
graph->RenderFile(path.c_str(), 0);
This crashes on the AddRef() due to an access violation. I've already tried implementing the IUnknown of the class myself, and the best I got was to the AddFilter where it crashed because the IBaseFilter seemed to be invalid. After that I found even a Microsoft-issued example doing this the simple way and it seems to work for them. I'm curious what might be wrong since I'm doing the same exact thing - even tried the smart pointers.
EDIT: The problem is in the CBaseFilter DECLARE_IUNKNOWN macro, the GetOwner()->AddRef fails. GetOwner itself seems to work.
GetOwner returns whatever you pass as the second parameter to the CBaseFilter constructor. Normally NULL unless you are aggregating the object for some reason (if you are, you probably don't need to).
A crash can occur at that point if your release build is linking against Strmbasd.lib, which is the debug version of the DirectShow base class library.
Change your project's release configuration to link against Strmbase.lib instead, which is the release version of the library.

ActiveX HWND, DirectX WindowLess mode

I would like to render video in ActiveX control (not in pop-up DirectShow window). I have:
IID_IVMRWindowlessControl
IID_IVMRFilterConfig9
CLSID_VideoMixingRenderer9
I would like to set WindowLess mode, but I don't know how to get HWND of..., exactly, of what? IEFrame, HTML element?
hr = pWc->SetVideoClippingWindow(???);
Anyone with some hint?
Regards.
First of all, add this to the constructor of your ActiveX control:
// this seemingly innocent line is _extremely_ important.
// This causes the window for the control to be created
// otherwise, you won't get an hWnd to render to!
m_bWindowOnly = true;
Your ActiveX control will have a member variable called m_hWnd that you'll be able to use as a render target. without the m_bWindowOnly variable set true, the ActiveX control won't create its own window.
Finally, pick your renderer (VMR9 for example)
CRect rcClient;
CComPtr<IBaseFilter> spRenderer;
CComPtr<IVMRWindowlessControl9> spWindowless;
// Get the client window size
::GetClientRect(m_hWnd, rcClient);
// Get the renderer filter
spRenderer.Attach( m_pGraph->GetVideoRenderer() );
if( ! spRenderer )
return E_POINTER;
spWindowless = spRenderer;
if( spWindowless )
{
spWindowless->SetVideoClippingWindow( m_hWnd );
spWindowless->SetVideoPosition(NULL, rcClient);
spWindowless.Release();
}
spRenderer.Detach();
Please note that my graph object is a custom object and that GetVideoRenderer() is one of my own functions - it returns an IBaseFilter*.
It took me ages to find this one out. ATL is poorly documented, which is a shame, because it's an excellent technology. Anyways, hope this helps!
freefallr's info is extremely helpful, but I don't think it answers your question completely. The trick with windowless activex controls is that you don't get a window. When you draw you'll just basically get a device context and you have to respond to call from the browser and only draw when it tells you to.
The interfaces required are here: http://msdn.microsoft.com/en-us/library/ms682300%28v=VS.85%29.aspx
more info here: http://msdn.microsoft.com/en-us/library/aa751970%28VS.85%29.aspx#OC96_and_Windowless_
We've been meaning to add support for this in FireBreath (http://firebreath.org) for awhile; we have support for it in all npapi browsers, but looks like we don't (yet) support IE. If you find more details, post a summary here =]

C++ - Basic WinAPI question

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.

"Debug Assertion" Runtime Error on VS2008?

I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when I first run the program sometimes. When I try to debug it, it takes me to this winhand.cpp file which is not part of the program I wrote so I'm not sure how to debug this.
It takes the error to this place in winhand.cpp
CObject* pTemp = LookupTemporary(h);
if (pTemp != NULL)
{
// temporary objects must have correct handle values
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h || ph[0] == NULL);
if (m_nHandles == 2)
ASSERT(ph[1] == h);
}
So why does this error happen? Why does it only happen sometimes (50% of the time)? How would I debug this?
I'll provide some code if is needed.
THANKS!
The code that is asserting is part of MFC's CHandleMap class. MFC deals with windows as CWnd objects, but Windows deals with them as HWND handles. the handle map allows MFC to 'convert' an HWND into a pointer to the MFC object representing that object.
What the assertion seems to be doing is checking that when a lookup of the handle finds an MFC object, that the MFC object also thinks it's wrapping the same handle.
If they're different, then you get the assertion.
So it would appear that something is corrupting the handle map or the MFC object for that handle or you're doing something incorrect that gets these 2 data structures out of sync.
Some things you might do to try to debug the problem is to determine:
what MFC object is being found in the lookup (that's what's being pointed to by pObject)
what the MFC object thinks it's wrapping (that's the handle ph[0] and/or ph[1] - I'm not sure why there can be 2 of them)
what the handle is for (that's h)
Do the handles look like handle values or do they look like garbage? Does pObject point to something that looks like an MFC object, or garbage? Do any of these these things seem related?
The answers to these questions may point to what you need to do next (maybe set a debug write breakpoint on the item that looks like it's trashed).
I got this same assertion few days ago, and after some google search,
I found the solution for my case here:
http://forums.codeguru.com/showthread.php?216770-What-would-cause-this-assertion
In my case, change to misused
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();
to
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);
would fix it.
Look out for code along those lines (from memory from Stroustrup's book):
c1 = (t2+t3).c_str();
(in spirit, could be other commands and expressions of course).Temporary objects are destroyed after their enclosing full expression has been evaluated, or at least the standard allows them to be. That means that what you would like to allocate to c1 may, or may not, still be in memory where it can be assigned to c1. The compiler may alert you to this issue, and the issue may or may not arise depending on what exactly you assign and other circumstances (I am not compiler writer), which would also explain why you get this error message only sometimes.
So in your shoes, I'd scan my code for similar expressions and clean them up.
When the debugger breaks, head up the call stack to the first bit of your code (if there is any - hopefully there is!). Ideally it's as simple as something in your code calling a library function incorrectly, and the library is catching the error with an assert and alerting you to that. (I don't think anyone will be able to tell what's wrong from the library code, we need to see your code.)
Otherwise, you're in for some tricky debugging: you're doing something wrong with the library that is asserting (looks like MFC) so go back and review all your MFC code and make sure everything is correct and according to the documentation.
This looks suspiciously like an error I had this morning. Is this happening in OnIdle()?
I know this is a very old post, but hoping that someone may get a little help from my answer.
I also faced a similar issue recently because of my simple mistake, then I came across this post and got a hint from "pac"'s post.
What I found is that if I use DeleteDC() to release DC returned from GetWindowDC() or GetDC() I will get the above assertion in MFC frame once CPaintDC object instance goes out of scope.
CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);
You have to use DeleteDC() only in conjunction with CreateDC() API.
CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();
We had this problem when some of our project dlls were linking MFC as static library and some as shared library (check "Use of MFC" in Project settings)