How to have the changes stay? - c++

I have MainScreen.cpp
void MainScreen::Show(D2DResources* pD2DResources)
{
HRESULT hr = S_OK;
ID2D1Bitmap* pBitmap=pD2DResources->GetpCurrentScreen();
hr = pD2DResources->LoadBitmapFromFile(
pD2DResources->GetpRT(),
pD2DResources->GetpIWICIF(),
L".\\Images\\MainScreen.jpg",
0,
0,
&pBitmap
);
if(SUCCEEDED(hr))pD2DResources->DrawScreen();
}
and at some point the MainScreen::Show() function is called like this
MainScreen->Show(&d2DResources);
However, it seems that as pD2DResources calls DrawScreen() in the MainScreen::Show() function, whatever was stored into &pBitmap didn't save. Actually, I get an unhandled exception and as it happens, pCurrentScreen, which should have received pBitmap's value, is 0x00000000.
What should I do?

As you know, LoadBitmapFromFile function failed
So you should check LoadBitmapFromFile function's arguments
However why did you assign pD2DResources->GetpCurrentScreen() to pBitmap??
Next line, pBitmap will be assigned with LoadBitmapFromFile function again.
Additionally, If MainScreen's Show function called every frames, that is not efficient.
Because you don't have to load bitmap every frames.
And d2d bitmap should be released.

Related

D3D11CreateDeviceAndSwapChain Fails With E_ACCESSDENIED When Using Same HWND

If I create a window and pass the HWND to D3D11CreateDeviceAndSwapChain, it works. However, after I release the device, context, swapchain, etc and try to repeat the process using the same HWND, D3D11CreateDeviceAndSwapChain fails with E_ACCESSDENIED. This tells me something must be holding onto the HWND, but what? I release all my global variables in the destructor of the class. Anyone have an idea what the problem is?
~decoder()
{
m_VertexShader->Release();
m_VertexShader = nullptr;
m_PixelShader->Release();
m_PixelShader = nullptr;
m_InputLayout->Release();
m_InputLayout = nullptr;
device->Release();
device = nullptr;
context->Release();
context = nullptr;
swapchain->Release();
swapchain = nullptr;
rendertargetview->Release();
rendertargetview = nullptr;
m_SamplerLinear->Release();
m_SamplerLinear = nullptr;
HRESULT hr = S_OK;
hr = decoder_transform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, NULL);
hr = decoder_transform->ProcessMessage(MFT_MESSAGE_NOTIFY_END_STREAMING, NULL);
hr = decoder_transform->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, NULL);
decoder_transform.Release();
color_transform.Release();
hr = MFShutdown();
}
While D3D11CreateDeviceAbdSwapChain does not mention why this is happening in the documentation, it is essentially just a wrapper around creating a D3D11Device and swap chain. The documentation for IDXGIFactory2::CreateSwapChainForHwnd does go into detail on why this is happening.
Because you can associate only one flip presentation model swap chain at a time with an HWND, the Microsoft Direct3D 11 policy of deferring the destruction of objects can cause problems if you attempt to destroy a flip presentation model swap chain and replace it with another swap chain. For more info about this situation, see Deferred Destruction Issues with Flip Presentation Swap Chains.
The documentation regarding Deferred Destruction Issues with Flip Presentation Swap Chains advises calling ID3D11DeviceContext::ClearState followed by ID3D11DeviceContext::Flush.
However, if an application must actually destroy an old swap chain and create a new swap chain, the application must force the destruction of all objects that the application freed. To force the destruction, call ID3D11DeviceContext::ClearState (or otherwise ensure no views are bound to pipeline state), and then call Flush on the immediate context. You must force destruction before you call IDXGIFactory2::CreateSwapChainForHwnd, IDXGIFactory2::CreateSwapChainForCoreWindow, or IDXGIFactory2::CreateSwapChainForComposition again to create a new swap chain.

Default HRESULT hResult = E_NOTIMPL?

I am working on a win7 based system using silverlight for embedded for UI graphics and C++ for firmware. I have noticed that in many of the existing functions (written before i was brought onto the project), there is some code that i am not quite sure what it is doing.
HRESULT AddAlarm::AlarmType_SelectionChanged (IXRDependencyObject* pSender, XRSelectionChangedEventArgs* pArgs)
{
HRESULT hResult = E_NOTIMPL;
if((NULL == pSender)||(NULL==pArgs))
{
hResult = E_INVALIDARG;
}
//Code to set visibility of UI elements
if(index ==0) //index is the threshold type index from the combobox. Can be 0-3.
{
m_pAlarmLowThreshold->SetVisibility(XRVisibility_Collapsed);
}
//Code repeats for other threshold types and visibility states.
return hResult;
}
The if statement is pretty straightforward and the function returns hResult, but i dont understand the declaration HRESULT hResult = E_NOTIMPL;. It is declaring a variable of type HRESULT and assigning it a default HRESULT value of E_NOTIMPL, but since the function doesnt modify this value outside of the if statement, doesnt this mean that it remains as E_NOTIMPL, basically telling the system that it (something) is not implemented or is wrong?
I know that when this king of method is automatically generated trought the VS interface. The inside code is always something like
return E_NOTIMPL;
I think what your predecessors tried to do is beeing clean in there way to develop the method by assuring them self that all case are processed by starting with an E_NOTIMPL that should be changed during method's processing.
This kind of method should return s_OK when it works fine. Here is a list of possible codes :
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378137%28v=vs.85%29.aspx
If there is no assigning of an S_OK it means indeed that the function is not fully implemented thus an E_NOTIMPL seems correct (or not :) )

CBitmap::GetBitmap Failure

What could be the possible reasons of getting return code as 0 from GetBitmap()?
BITMAP bmInfo;
int rc = bitmap->GetBitmap (&bmInfo);
int ec = GetLastError();
The value returned by GetLastError() is also 0. MSDN doesn't give any help and all the forums where similar questions have been asked are silent.
To give you some context, I have an instance of CBitmap and I am attaching a second instance of CBitmap to the same HBITMAP using code similar to the following:
CBitmap first;
:
:
CBitmap second;
second.Attach ((HBITMAP)first);
BITMAP bmInfo;
second.GetBitmap (&bmInfo);
The call to GetBitmap() fails for second and not for first.
The call to GetBitmap() fails for second and not for first.
If so, there is no way the two class instances hold the same handle, and your code snippet suggests exactly this. You can break with debugger to check your first and second to find out what they are actually holding inside.

C++ access violation when calling instance method

I'm creating a DirectX 11 helper class that looks kind of like this:
#import "DXClass.h" // I have declared the constructor and the other methods here
// All of the DirectX libraries are imported in the header as well
DXClass::DXClass()
{
// Pointers created, etc.
}
DXClass:~DXClass()
{
// Other DirectX objects released
// With an if (bbSRView) {}, the exception still occurs, so bbSRView is not NULL
// bbSRView is a ID3D11ShaderResourceView*
// When the other violation does not occur, one does here:
bbSRView->Release();
bbSRView = NULL;
// More releases
void DXClass::Initialize()
{
SetupDisplay();
// Other initialization that works fine
}
void DXClass::SetupDisplay()
{
// This is where the debugger shows the access violation.
// factory is declared as DXGIFactory*
HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&factory);
// Loop through adapters and outputs, etc.
}
This class is initialized like this: dxClass = new DXClass();
The Initialize() function is called in another method of the class that created dxClass.
When the application is run, I get an access violation at the beginning of the setupDisplay() function. However, if I take the code in setupDisplay() and put it in Initialize(), removing the call to setupDisplay(), no access violation occurs. Also, if I remove the code from setupDisplay() so that it is an empty function, and then call it in Initialize(), no access violation occurs.
It appears that no pointers are NULL, and the application will start fine if it is changed as described above. However, on another note, the application receives another access violation when quitting. The debugger points to a Release() call on an ID3D11ShaderResourceView*, which I have pointed out in my code snippet. This pointer also appears to be valid.
I have also checked the similar questions, but the this pointer of the class appears to be valid, and I am not creating any buffers that could be overflowing. There also isn't anything that could be deleting/freeing the object early.
I have no idea what could be causing the errors. :/
Thanks :D
EDIT:
Here's an isolated test, with the same errors:
I have in my main function:
INT APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, INT)
{
App *app = new App();
app->Run();
app->Release();
}
In my App class, I have removed all window functionality and any other variables so that it looks like this:
App::App()
{
dxClass = new DXClass();
}
App::~App()
{
delete dxClass;
}
void App::Run()
{
dxClass->Initialize();
while (true) {} // Never reaches here
}
The access violation still occurs at the same place. Also, same results if I replace the factory instance variable with:
IDXGIFactory *f;
HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void **)&f);
Which has worked for me in other applications.
An access violation when calling Release() usually means the object has already received it's final Release() from somewhere else (and it has destroyed itself). One possible solution would be to AddRef() when passing the pointer into your DXClass

Under what conditions is CCmdTarget::OnFinalRelease called?

The MSDN documentation for the CCmdTarget::OnFinalRelease method is pretty brief:
Called by the framework when the last OLE reference to or from the
object is released.
I have created a sub-class of CCmdTarget
class CMyEventHandler : public CCmdTarget { ... }
I'm trying to figure out under what conditions the OnFinalRelease method will be called. I have some code that looks something like this:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
Using this code, I observe that the OnFinalRelease method is never called. This means I have a memory leak. So I modified the wrap-up code as follows:
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
delete myEventHandler;
myEventHandler = NULL;
This section of code is triggered off periodically throughout the day. What I notice now is that, while the destructor for the wrapped up instance of myEventHandler is called as expected, the OnFinalRelease function is getting called now! What's worse, it is being called not on the instance that has been wrapped up, but instead on a newly created instance of CMyEventHandler! Thinking that this might be due to a reference counting issue, I modified my wire-up and wrap-up code:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
delete myEventHandler;
myEventHandler = NULL;
I let this run all day and now observe that OnFinalRelease is never called. The destructor for the wrapped up instance is called as I would expect, but I'm left feeling uneasy as I clearly don't understand the circumstances under which OnFinalRelease is called. Is OnFinalRelease called on some delay, or is there a way to force it to fire? What will trigger OnFinalRelease to be called?
If it matters, the event source is a .NET assembly exposing events via COM interop.
With COM you should always use the CoCreateInstance() AddRef() and Release() paradigm to manage lifetime of your objects, and let COM do the destruction of your objects based on reference counts. Avoid new and delete because using them breaks this paradigm and causes interesting side effects. You probably have a bug in the management of the reference counts.
The way to debug why the reference counts are not being managed correctly is to override CCmdTarget::InternalRelease() copy the source from oleunk.cpp and put some trace output or break points.
DWORD CMyEventHandler::InternalRelease()
{
ASSERT(GetInterfaceMap() != NULL);
if (m_dwRef == 0)
return 0;
LONG lResult = InterlockedDecrement(&m_dwRef);
if (lResult == 0)
{
AFX_MANAGE_STATE(m_pModuleState);
OnFinalRelease();
}
return lResult;
}
There are lots of times when passing IDispatch interfaces that code will bump reference counts and you have to decrement the reference count using Release(). Pay attention to where your code may be passing this interface because there is aconvention in COM that when Interfaces are passed using [in] or [out] where the caller or callee has to release the interface.
When the reference count issue is corrected you shoudl see the objects OnFinalRelease code being called and the object destoryed by hte MFC framework:
For CCmdTarget the destruction should happen as a result of the final
release in the parent class CWnd:
void CWnd::OnFinalRelease()
{
if (m_hWnd != NULL)
DestroyWindow(); // will call PostNcDestroy
else
PostNcDestroy();
}
FYI: Passing interfaces across threads without marshalling the interface pointers is another common reason to get errors in COM.
It doesn't appear that you ever call myEventHandler->Release(). Therefore, the last reference is never released, and OnFinalRelease is never called.