CBitmap::GetBitmap Failure - mfc

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.

Related

Is there a _safe_ way to send a string via the PostMessage?

I want to raise this question one more time. I wrote a comment on the accepted answer already, but, it seems, the answered person is inactive on the SO. So, I copy my comment-question here.
In the accepted answer on the referred question, there is a potential risk of the memory leakage. For example, the PostMessage can be resulted with error because of the messages queue is full. Or, the target window may be already destroyed (so, the delete operator will not be called).
As a summary, there is no a strong corresponding between the posting and the receiving of the Windows message. But, on the other hand, there are not so many options how to pass a pointer (to a string, for example) with the Windows message. I see only two: to use objects allocated in the heap or declared as the global variables. The former one has the difficulty which is described here. The latter one is deprived of the specified disadvantage, but there is need to allocate some memory which may be used rarely.
So, I have these questions:
May someone suggest a way, how we can be safe against the memory leakage in the case of using of the heap memory for "attaching" something to the Windows message?
Is there some another option how we can reach the goal (send a string, for example, within the Windows message via the PostMessage system call)?
use std::wstringstream.
look for EM_STREAMOUT.
wchar_t remmi[1250];
//make stuff
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
hc=CreateWindowEx(WS_EX_NOPARENTNOTIFY, MSFTEDIT_CLASS,remmi,
ES_MULTILINE|ES_AUTOVSCROLL| WS_VISIBLE | WS_CHILD
|WS_TABSTOP|WS_VSCROLL,
1, 350, 450, 201,
this->m_hWnd, NULL, h, NULL);
return 0;
}
//middleware
DWORD CALLBACK E(DWORD_PTR dw, LPBYTE pb, LONG cb, LONG *pcb)
{
std::wstringstream *fr = (std::wstringstream *)dw;
fr->write((wchar_t *)pb, int(cb/2));
*pcb = cb;
return 0;
}
//final
void CMainFrame::tr()
{
std::wstringstream fr;
EDITSTREAM es = {};
es.dwCookie = (DWORD_PTR) &fr;
es.pfnCallback = E;
::SendMessage(hc, EM_STREAMOUT, SF_TEXT|SF_UNICODE, (LPARAM)&es);
ZeroMemory(remmi,1218*2);
fr.read(remmi,747);
}

Why does CDC::SelectObject(CFont*) accept a CFont object vs. a pointer?

CPaintDC dc(this);
CFont font;
dc.SelectObject(font); // why does this build?
The function CDC::SelectObject takes a pointer of type CFont but why does this build with providing an object? I came across this issue that the above code is unpredictable and can crash sometimes but not always.
The code in question is valid, sort of. It compiles due to a combination of two things:
The CFont::operator HFONT().
An undocumented CDC::SelectObject overload taking an HGDIOBJ handle.
When the compiler tries to match an overload for dc.SelectObject(font), none of them match. So next it tries the user-defined conversion operator (operator HFONT()) that returns an HFONT. That matches the undocumented overload taking an HGDIOBJ (both HGDIOBJ and HFONT are typedef'd as void*).
The code posted in the question is almost correct, too, with 2 exceptions:
The font object is destroyed while still being selected into a device context. While this causes a double-delete bug (the font object is owned by the CFont instance and the device context), the call to DeleteFont gracefully fails when passed an invalid handle.
The font object previously selected into the device context is lost, and thereby leaked.
Neither issue causes unpredictable behavior or intermittent crashes. As explained in your answer, the real code, however, looks like this:
CFont* pOldFont = (CFont*) dc.SelectObject(font);
That is a bug that exhibits undefined behavior. dc.SelectObject(font) returns an HGDIOBJ (typedef'd as void*), which is subsequently cast to an unrelated type (CFont*). While storing the font previously selected into the device context to later restore it is correct, the code is not. An implementation that honors ownership could be:
CPaintDC dc(this);
CFont font;
CFont oldFont;
// Transfer ownership of font to the DC, and the previously selected font into oldFont
oldFont.Attach(dc.SelectObject(font.Detach()));
// Use dc
// Transfer ownership back
font.Attach(dc.SelectObject(oldFont.Detach()));
// oldFont goes out of scope; this a no-op since it no longer owns any resources
// font goes out of scope, releasing all resources owned by it
// dc goes out of scope, releasing all resources owned by objects selected into it
If you are willing to temporarily sacrifice strict ownership semantics, you can make your life easier by using the more standard implementation:
CPaintDC dc(this);
CFont font;
CFont* pOldFont = dc.SelectObject(&font);
// Use dc
dc.SelectObject(pOldFont);
This is safe, even if you exit early, without restoring the device context. It would still lead to a double-delete on the font object owned by both the CFont instance and the device context (which is handled gracefully by the API). It doesn't exhibit a font leak, though, because things are more complicated than it seems: There is another invisible owner involved here, a map controlled by MFC that stores temporary objects (like those returned from CGdiObject::FromHandle, which SelectObject(CFont*) calls). The temporary objects are cleaned up as part of MFC's idle time processing.
I agree with answer by IInspectable and here is my own proof of concept how this works:
#include "stdafx.h"
#include <iostream>
class A {
int a_int = 6;
char* a_carp = "A derived";
public:
operator int() { return a_int; }
operator char*() { return a_carp; }
};
class B : public A {
float b_float = 5.7;
char* b_carp = "B Derived";
public:
operator float() { return b_float; }
operator char*() { return b_carp; }
};
void Print(char * text)
{
std::cout << text << std::endl;
}
int main() {
B b_obj;
// long a = b_obj;
char* c_p = b_obj;
Print(b_obj);
return 0;
}
The above code builds and the output is "B Derived".
How does it works?
When we use an object in place of a different type, the object looks for appropriate conversion operator. If it finds it, it applies it and converts that for you.
In this case, that operator was HFONT(). It is important to note the actual name of the operator doesn't matter, its the return type/signature that matters. So when it finds a match (correct signature), it calls it.
Why unpredictable behavior?
Let me clear that as well since I mention that in OP. The code I posted was related to build issue but the actual code was this:
CFont* pOldFont = (CFont*) dc.SelectObject(font);
And the forced typecasting (CFont*) was the problem. If we pass HGDIOBJ to SelectObject(), it returns HGDIOBJ but it was forced typecasted to CFont * and that was the problem so there is nothing else wrong with using conversion operators.

How to have the changes stay?

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.

heap corruption when deconstructing sf::Image array

so I'm trying to make a fade transition animation for an sf::Image in SFML, and I'm have a small problem.
When I don't comment out the function called below, I get an error at the end of main() when the images are being deconstructed saying
"Windows has triggered a breakpoint. This may be due to a corruption
of the heap."
The line this happens on contains the code GLCheck(glDeleteTextures(1, &Texture));
Why would this be happening, and why only when CreateTransition() is run?
One more note: when I comment out aray[I] = aray[0] the break doesn't occur.
I posted the function below.
void CreateTransition(sf::Image& start, sf::Image animationArray[numbImgs]){
animationArray[0] = start;
void threadFunc(void* imgArray);
sf::Thread thread(threadFunc, reinterpret_cast<void*>(animationArray));
thread.Launch();
thread.Wait(); // comment this out once I get the code working
}
void threadFunc(void* ptr){
sf::Image* aray = reinterpret_cast<sf::Image*> (ptr);
sf::Color filter(0, 0, 0, 5);
for(int I= 1; I< numbImgs; I++){
//aray[I].Copy(aray[0], 0, 0, sf::IntRect(0, 0, 0, 0), true);
aray[I] = aray[0]; // error doesn't occur when commented out
RecolorImage(aray[I], filter);
}
}
Image& Image::operator =(const Image& Other)
{
Image Temp(Other);
std::swap(myWidth, Temp.myWidth);
std::swap(myHeight, Temp.myHeight);
std::swap(myTextureWidth, Temp.myTextureWidth);
std::swap(myTextureHeight, Temp.myTextureHeight);
std::swap(myTexture, Temp.myTexture);
std::swap(myIsSmooth, Temp.myIsSmooth);
std::swap(myNeedArrayUpdate, Temp.myNeedArrayUpdate);
std::swap(myNeedTextureUpdate, Temp.myNeedTextureUpdate);
myPixels.swap(Temp.myPixels);
return *this;
}
A few things which might help you narrow down the cause:
A heap corruption rarely occurs at the point when the program crashes which makes them hard to track down. It may be related to the object at the crash point or it may have been another object/code that corrupted it.
In CreateTransition() you pass the animationArray[] by value but you then pass it into a thread procedure. The lifetime of animationArray[] ends when you return from CreateTransition() which means if the thread procedure runs after this point its void* ptr parameter will not point to a valid object. You do have a thread.Wait() in the current code but also a comment about removing it. Either pass animationArray[] by reference unless there is a specific reason not to, or create a temporary copy for the thread procedure to ensure it operates on valid objects.
Consider using a std::vector<sf::Image> instead of an array.
Make sure you understand and implement the Rule of Three for sf::image and any dependent classes (like MyPixels). Not doing this can result in double-frees, leaked memory, and heap corruption like you are seeing.
If all else fails try to duplicate the issue in a temporary test project and reduce it to the smallest amount of code possible. Eliminate members of sf::image one at a time until the problem goes away. Similarly, delete lines from CreateTransition() and other lines from the thread procedure. You'll either end up with a few very specific lines that trigger the issue or an empty project.

Uninitialized read problem

Program works fine (with random crashes) and Memory Validator reports Uninitialized read problem in pD3D = Direct3DCreate9.
What could be the problem ?
init3D.h
class CD3DWindow
{
public:
CD3DWindow();
~CD3DWindow();
LPDIRECT3D9 pD3D;
HRESULT PreInitD3D();
HWND hWnd;
bool killed;
VOID KillD3DWindow();
};
init3D.cpp
CD3DWindow::CD3DWindow()
{
pD3D=NULL;
}
CD3DWindow::~CD3DWindow()
{
if (!killed) KillD3DWindow();
}
HRESULT CD3DWindow::PreInitD3D()
{
pD3D = Direct3DCreate9( D3D_SDK_VERSION ); // Here it reports a problem
if( pD3D == NULL ) return E_FAIL;
// Other not related code
VOID CD3DWindow::KillD3DWindow()
{
if (killed) return;
diwrap::input.UnCreate();
if (hWnd) DestroyWindow(hWnd);
UnregisterClass( "D3D Window", wc.hInstance );
killed = true;
}
Inside main app .h
CD3DWindow *d3dWin;
Inside main app .cpp
d3dWin = new CD3DWindow;
d3dWin->PreInitD3D();
And here is the error report:
Error: UNINITIALIZED READ: reading register ebx
#0:00:02.969 in thread 4092
0x7c912a1f <ntdll.dll+0x12a1f> ntdll.dll!RtlUnicodeToMultiByteN
0x7e42d4c4 <USER32.dll+0x1d4c4> USER32.dll!WCSToMBEx
0x7e428b79 <USER32.dll+0x18b79> USER32.dll!EnumDisplayDevicesA
0x4fdfc8c7 <d3d9.dll+0x2c8c7> d3d9.dll!DebugSetLevel
0x4fdfa701 <d3d9.dll+0x2a701> d3d9.dll!D3DPERF_GetStatus
0x4fdfafad <d3d9.dll+0x2afad> d3d9.dll!Direct3DCreate9
0x00644c59 <Temp.exe+0x244c59> Temp.exe!CD3DWindow::PreInitD3D
c:\_work\Temp\initd3d.cpp:32
Edit: Your stack trace is very, very strange- inside the USER32.dll? That's part of Windows.
What I might suggest is that you're linking the multi-byte Direct3D against the Unicode D3D libraries, or something like that. You shouldn't be able to cause Windows functions to trigger an error.
Your Memory Validator application is reporting false positives to you. I would ignore this error and move on.
There is no copy constructor in your class CD3DWindow. This might not be the cause, but it is the very first thing that comes to mind.
If, by any chance, anywhere in your code a temporary copy is made of a CD3DWindow instance, the destructor of that copy will destroy the window handle. Afterwards, your original will try to use that same, now invalid, handle.
The same holds for the assignment operator.
This might even work, if the memory is not overwritten yet, for some time. Then suddenly, the memory is reused and your code crashes.
So start by adding this to your class:
private:
CD3DWindow(const CD3DWindow&); // left unimplemented intentionally
CD3DWindow& operator=(const CD3DWindow&); // left unimplemented intentionally
If the compiler complains, check the code it refers to.
Update: Of course, this problem might apply to all your other classes. Please read up on the "Rule of Three".