Acces Violation when trying to use MFC object - c++

I am working on a MFC project with Kinect that uses a FPS counter. This is a static text. I want this FPS counter to be editted by a method which is also responsible for make the kinect images. So in my main I pass the HWND on to my kinect object like this:
kinect->initialize(this->GetSafeHwnd());
In my kinect object this thing gets saved:
this->hwnd = hWnd;
and then this piece of code to initialize the Static Text I want to use:
CStatic * MFC_ecFPSCOLOR;
MFC_ecFPSCOLOR = (CStatic *) GetDlgItem(hWnd, TC_FPSCOLOR);
And then I want to use it:
MFC_ecFPSCOLOR->SetWindowTextW(L"TEST");
And here it goes wrong:
Unhandled exception at 0x54431C19 (mfc110ud.dll) in KinectMain.exe: 0xC0000005: Access violation reading location 0x0031004C.
Can someone point me in the right direction?

You're using the wrong version of GetDlgItem, it returns a handle and not a CWnd*. The cast is hiding the error from you.

Related

Direct2D : Unhandled Exception In WM_RESIZE switch case

I am creating a Simple Direct2D Application. Unfortunately it is giving
an unhandled exception. The function where it is taking place:
void DemoApp::OnResize(UINT width, UINT height)
{
if (m_pRenderTarget) <----|****The exception occurs here.....****
{
// Note: This method can fail, but it's okay to ignore the
// error here, because the error will be returned again
// the next time EndDraw is called.
m_pRenderTarget->Resize(D2D1::SizeU(width, height));
}
}
And the code snippet calling OnResize() is:
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pDemoApp->OnResize(width, height);
}
result = 0;
wasHandled = true;
break;
/*rest of switch case*/
}
The exception says:
Unhandled exception at 0x00007FF6BE402CCA in Simple Direct2D application.exe: 0xC000041D: An unhandled exception was encountered during a user callback. occurred
Exception screenshot:
As soon as I start to debug, the program, it gives the exception.I even copied the program word by word from the site.As I am new to the world of DirectX, I am clueless about the exception. What should I do?
I've compiled that sample. It works in 32-bit builds, crashes in 64-bit builds.
The error is in Microsoft's sample code and is unrelated to Direct2D.
They pass this into SetWindowLongPtr, in combination with PtrToUlong macro for type conversion. In 64-bit builds, this is 8-bytes long, SetWindowLongPtr also accepts 8 bytes, however PtrToUlong macro converts to unsigned long which is only 4 bytes. So PtrToUlong macro drops higher 4 bytes from this pointer, and the app fails spectacularly.
You can fix by replacing PtrToUlong( pDemoApp ) with (LONG_PTR)pDemoApp
P.S. I think the root cause is, MS pretends very hard Win32 platform is obsolete, pushes developers to UWP instead. That’s why in their DirectX and Direct2D samples, they don’t use their own ATL, because it’s desktop-only library. Using ATL would dramatically simplify these samples: CComPtr for interface pointers, CWindowImpl for windows creation and message handling, and lots more.
Update: here's a better sample.
Since you are getting an exception in a point where you are doing nothing but reading a member variable, the only possible reason I can think of is that your this pointer is garbage. While it is common for window message handlers to be called before SetWindowLong has been called, in which case the value returned by GetWindowLong is null, you (correctly) check that it isn't, and this is confirmed by your screenshot (as well as the fact that it's garbage). The possible options left are that either what you pass to SetWindowLong is not a pointer to a valid DemoApp object, or that it once was but the object is no longer valid when the message is received. So, as an answer to your question, you should check that
the value you pass to SetWindowLong really is a valid pointer to a DemoApp
the DemoApp whose pointer you pass is in the heap or a global variable, not a local variable that can go out of scope during the lifetime of the window
you don't delete your DemoApp object, if it is heap allocated, during the lifetime of your window
Also, you are explicitly using the Unicode version of GetWindowLongPtr, which is also used in the original example (with no explanation why). Check your project settings that you are compiling an Unicode application.

Visual C++ CLR How to convert a picture box's handle to a managed pointer (PictureBox ^_pbPic )

I am writing a dll which receives a picture box'handle in a call like:
**Declare Sub ERPInitialize Lib "C:\Desenv\EBioNet\EBioNet\Debug\ERPDll.dll" (ByVal PicHandle As Long)**
and it is called in this way:
**Call ERPInitialize(PictureBox1.Handle)**
I would like to store this handle and get back the PictureBox1's managed pointer back from the stored handle so that I can draw an image on it.
Any clue?
Thanks in advance
If I pass PictureBox^ in the the call ERPInitialize I cannot stored it, for later use as a global, because managed pointers are not allowed in CLR.
I tried
PictureBox ^_pbPic;
IntPtr Ptr_Picturebox = (IntPtr)PictureHWD;
GCHandle handle2 = (GCHandle)Ptr_Picturebox;
_pbPic = (PictureBox ^ )(handle2.Target);
but it causes an exception 0xc0000005.

MFC "memory allocation violation"

I created a check box in a dialog box and trying to access its condition whether checked or not. This is my code:
CButton *m_ctlCheckBlack = (CButton *)GetDlgItem(IDC_BLACK);
int chkBoxBlack = m_ctlCheckBlack->GetCheck();
As I run through this code, it pops up an exception saying :
Exception thrown at 0x0FA45564 (mfc140d.dll) in braille_obr.exe: 0xC0000005:
Access violation reading location 0x00000020.
any help will be appreciated. thank you.
There is rarely a good reason to use GetDlgItem. In your resource editor, right click the button and 'Add Variable..'
It will default as a control. Give it a name. You will get a member in the dialog class:
CButton myButtonName;
Now it should be safe to:
myButtonName.GetChecked( );
as it will have been created and properly subclassed.
Perhaps, I doubt it tried to get the state of button when the Button was not yet constructed.
int chkBoxBlack = m_ctlCheckBlack != NULL ? m_ctlCheckBlack->GetCheck() : 0;
Or, do you try to operate from outside dialog?
If it is so, you had better try to do this.
■CButton *m_ctlCheckBlack = (CButton *)yourdlg.GetDlgItem(IDC_BLACK);
■FindWindowEx(yourdlg.GetSafeHwnd(), NULL, NULL, "(your button caption)");

How can I "validate" CWnd* object?

(There's a TL;DR on the last line)
I'm implementing a handler to close selected windows open in a software application. Here's a rough code:
void CDlg_Dummy_Dialog::OnCloseWindows()
{
for (int i = 0; i < m_WindowsInfo.size(); i++) {
Window_Node *pWN = &m_WindowsInfo.at(i);
if (pWN->checked && IsWindow(pWN->pWnd->GetSafeHwnd())) {
pWN->pWnd->GetParentFrame()->SendMessage(WM_CLOSE);
}
}
}
Here are some declarations of the parameters shown above:
struct Window_Node {
CString name;
CString path;
CWnd *pWnd;
BOOL checked;
HICON icon;
....
};
class CDlg_Dummy_Dialog : public CDialog {
...
protected:
std::vector<struct Window_Node> m_WindowsInfo;
...
}
Also, there can be multiple instances of Window_Node with different pWnd parameter, originating from a single CDocument class (ie. different types of windows exist to show different displays for the document).
For this software, if the first window of the document (which is always the "green" Window type in the diagram) is closed, all other windows associated with that document will automatically be closed with them. This is where the problem happens.
If the user selects multiple windows from the same document (with the green window among them), it closes all windows by the time it finishes the first iteration, and all pWnd pointers are now pointing to a now unassigned memory. Therefore, when it tries to call GetSafeHwnd() on the next iteration, it prompts a memorry access violation error:
First-chance exception at 0x00000000521B4AD0 (mfc100d.dll) in Settle3D.exe: 0xC0000005: Access violation reading location 0x00000000136943E0.
Unhandled exception at 0x00000000521B4AD0 (mfc100d.dll) in Settle3D.exe: 0xC000041D: An unhandled exception was encountered during a user callback.
I'm aware that the easy fix would be to iterate through the vector in the opposite direction. However, I am trying to integrate this method on several other software as well, and they don't necessarily organize their windows in the same manner.
So, after all the long question above, here's TL;DR:
Is there any way to check if an instance of CWnd* is pointing to a valid window?
One possibility would be to start with your main window, and recursively search through the child windows if you find the HWND in question.
Get the first child with CWnd::GetWindow(GW_CHILD) and the next windows with CWnd::GetWindow(GW_HWNDNEXT).

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 =]