Ok, so basically, I have an SDL wrapper header called SDL_Video_wrapper.h. It contains two wrapper classes : CWindowWrap, and CRendererWrap in a namespce called detail. The user can access those classes via two shared pointers, defined as the following :
using CWindow = std::shared_ptr<detail::CWindowWrap>;//types Here are hidden from the user !
using CRenderer = std::shared_ptr<detail::CRendererWrap>;
And the users can create those shared_ptrs with this two methods :
CWindow construct_window(Window_properties p){
if (has_init_SDL_Video){
return std::make_shared<detail::CWindowWrap>(p.title, p.xPos, p.yPos, p.width, p.height, p.flags);
}
else
LOG("SDL_Wrapper", "Cannot construct Window : SDL hasn't been initialized !");
return nullptr;
}
and it's basically the same with my Renderer;vy
I have another function called QUIT_All_Subsystems, which shuts down everything in SDL.
SO, the problem is that I need my smart pointers to dispose automatically after Quit_All_Subsytems is called ( I automatically call it with atexit(Quit_All_Subsystem) )
Take a look at the shared pointer destructor here with an example provided: http://www.cplusplus.com/reference/memory/shared_ptr/~shared_ptr/
Hope this helps
Related
I am trying to keep a std::vector of Gtk::Widgets that I am showing (and will potentially be) moving around between Gtk::Containers.
At the moment I keep a Gtk::Notebook which is basically a one-to-one map to the std::vector, but if I use Glib::RefPtr around the widgets I get problems when removing the widget from the notebook. I already have to use a 'hack' to get a pointer to the underlying Gtk object when adding it to the notebook and I suspect that the Notebook container frees/deletes the object when I remove it from the container.
I have defined my vector of widgets something like this:
std::vector<Glib::RefPtr<Gtk::Widget>> widgets;
When I add a widget to the vector and the notebook I do:
Glib::RefPtr<Gtk::Widget> w (new Gtk::Widget());
widgets.push_back (w);
Gtk::Widget *wptr = w.operator->(); // hack
notebook.append_page (*wptr);
when I try to remove it I do:
int c = 1; // widget no. to remove
notebook.remove_page (c);
auto it = widgets.begin() + c;
widgets.erase (it);
but this results in a G_IS_OBJECT fail assertion when (I think) the element in the std::vector is cleaned up at the end of the iterator (end of function), since possibly notebook.remove_page() already freed the object. How can I do this? Is it possible with RefPtr's?
Related (same assertion failure): Destructing Glib::RefPtr causes failed assertions in the GTK 3 core
Glib::RefPtr<> should not be used with widgets. It is not a general purpose smartpointer. It should only be used with classes that force you to use it - by having no public constructor but having public create*() methods.
Unfortunately you can't do this because the Gtk::Notebook takes ownership of the child objects. You have to refactor your code to use the Gtk::Notebook itself to access the widgets instead of the vector, for example with Gtk::Notebook::get_nth_page().
I have a solution and it has two projects in it. When I got the code they told one project handles the visual part and the other has the logic part. Now I added one button to the window. To do that i edited the project which handles the visual part. I am very new to this but creating and adding buttons is fairly straightforward in visual studio 2010. Now the problem is I want to detect if the button is pressed from the other project. I am sure that the projects are sharing some data, but I am not being able to capture it. For now I am changing a value in a file and reading the same data from the other project to check if the button is pressed. But I think there is a better way to do it. Can anyone help?
I don't think the two projects are sharing automatically. You will have to define the interface that the two projects communicates. For instance, in your solution above the "a value in a file" is the "interface" you have defined. What sounds like you are trying to achieve is to separate the controller (logic part) and view (visual part) separately, which seems to indicate that your project is using MVC model.
I would suggest defining an abstract class (interface) that defines the interaction you want between the two projects. All they have to share is a single header file.
For example:
// Solution A (Controller - logic part)
// MyUIHandler.h
class IMyUIHandler //You can also use microsoft's interface keyword for something similar.
{
public:
HRESULT onButtonPressed() = 0; // Note that you can also add parameters to onButtonPressed.
};
HRESULT getMyUIHandler(IMyUIHandler **ppHandler);
Then implement this interface:
// Solustion A (Controller - logic part)
// MyUIHandler.cpp
#include "MyUIHandler.h"
class CMyUIHandler : public IMyUIHandler
{
private:
// Add your private parameter here for anything you need
public:
HRESULT onButtonPressed();
}
HRESULT getMyUIHandler(IMyUIHandler **ppHandler)
{
// There are many ways to handle it here:
// 1. Define a singleton object CMyUIHandler in your project A. Just return a pointer
// to that object here. This way the client never releases the memory for this
// object.
// 2. Create an instance of this object and have the client release it. The client
// would be responsible for releasing the memory when it's done with the object.
// 3. Create an instance of this object and have a class/method in Solution A release
// the memory.
// 4. Reference count the object, for example, make IUnknown the parent class of
// IMyUIHandler, and implement the IUnknown interace (which is boiler plate code).
// Since I don't know your project it's hard for me to pick the most suitable one.
...
*ppHandler = myNewHandler;
...
return S_OK;
}
CMyUIHandler can simply be your existing class that already handles some of the logic.
In solution B you should will call getMyUIHandler in some initialize function, for example the controller of the UI class, save that as your member. Then "Button clicked" event handler that VS creates for you.
// Solution B (View - visual part)
// MyUIView.h
class MyUIView
{
protected:
IMyUIHandler *m_pHandler;
}
// MyUIView.cpp
CMyUIView::CMyUIView(...)
{
...
hr = getMyUIHandler(&m_pHandler);
// error handler, etc...
...
}
// In the function that is created for you when button is clicked (I'm not sure if I get the signature right below.
void OnClick(EventArgs^ e)
{
...
hr = m_pHandler->onButtonPressed();
...
}
Then you can pass any parameter you define for the function onButtonPressed as soon as the button is clicked.
So I have this MFC dialog program I am working with. The dialogs are written but now I am having difficulty passing data around from dialog to dialog. I have the following structure _dlgDataHandler set up in a class derived from CWinApp and have have created a "new" statement for a pointer to this type.
//.......SRK.h file
class CSRK_App : public CWinApp
{
public:
CFSB_App();
// added the following data structure for data passing withing the program
typedef struct _dlgDataHandler {
char RepetitionRadio[24];
// another member
// yet another member and so on as necessary
} *dlgDataHandlerPtr;
// extern dlgDataHandlerPtr dlgDataHandler;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSRK_App)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CSRK_App)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//....... SRK.cpp A pointer to a new dataHandler created in this block about 2/3 the way down
// CSRK_App initialization
BOOL CSRK_App::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
//SetRegistryKey(_T("Local AppWizard-Generated Aplications"));
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
//CSRK_Dlg dlg;
CDialogMain dlg("SRK - Beta"); // added 12/27 **
m_pMainWnd = &dlg;
//const char* m_pszHelpFilePath = NULL;
//free((void*)m_pszHelpFilePath);
//m_pszHelpFilePath=_tcsdup(_T("c:\SRKHelp.rtf"));
// the following line added to allocate memory for the structure
dlgDataHandlerPtr dlgDataHandler = new _dlgDataHandler;
dlg.SetWizardMode(); // added 12/27 **
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
In the dialog .cpp files, there are five, I need to be able to get data from the AFX variables "m_" and load them into this dataHandler Structure (or another one like it) so that they can be used in other dialogs and parts of the program, specifically my actual code when all the dialog data collection is done. Someone said to use AfxGetApp() so that I could have a handle on the current instance but I do not understand what they are talking about. And yes I have read about it in many forums, I just don't get it. I further realize this is probably not the best way to do it. I am trying to learn MFC/OOP with what time I have available, but for now, I am just trying to get a handle on the basic process as I can tune it later once I understand how to collect and pass simple data around.
I further don't understand how calling AfxGetApp() will help me get a handle on the members of CSRK_App. It inherited CWinApps public members but AfxGetapp() can't see what CSRK_App has... can it?
First, to explain the AfxGetApp advice you have received. There is some extra hand-waving using 'new' and a pointer, but this is basically using a global variable for the structure that holds your data. This is not the best way to do what you are trying to do. There are many pitfalls.
AfxGetApp() is an MFC call that returns a pointer to your main App class derived from CWinApp.
If you want to use that returned pointer, you need to cast it as a CSRK_App* pointer with:
CSRK_App* pApp = static_cast <CSRK_App*> ( AfxGetApp());
Then you can use pApp->dlgDataHandlerPtr->... to access the variables you need.
Now, for the pitfalls. Someone else may chime in with a reason why the 'new' and the pointer are helpful, but I do not see any advantage to this approach as compared to just having a local variable dlgDataHandler inside your CSRK_App class. That would simplify the code.
The next issue is that all your data is public in a struct. Any dialog class that can call AfxGetApp can read or write any data in that struct. You have no way to control access.
Also, all of your dialog classes must now include SRK_App.h so they know the structure, and have access to all other variables in that App class.
A cleaner, object-oriented approach would be to declare the struct (class) for the data in a separate .h file that could be included in the dialog classes. Then, you would pass a pointer/reference to this data into the constructor of the dialog classes. The dialog class would have no need to know anything about the App class.
For an even higher level of segregation, the dialog classes can be written so they only get a copy of the dlgDataHandler class passed in before calling .DoModal(), and then after the DoModal call returns with IDOK, the App class can have control over which data from the dialog gets updated into the dlgDataHandler class. The advantage of this approach is that it insures that no matter how the dialog class is programed, the user can always "Cancel" the dialog without modifying any data.
I have a class which inherits from IDirectInputA interface.
here: http://pastebin.com/QuHP02ai
so, when i try to create object of this, application crashes (calls CorExitProcess from somewhere). What i did wrong?
p.s. Direct input v. 7
p.p.s.
this code creates object. I deleted some code from it, except the main part
IDirectInputA** ppDI;
HRESULT hr = _DirectInputCreateA(hinst, dwVersion, ppDI, punkOuter);
xDirectInputA xDI = new xDirectInputA((IDirectInputA*)(*ppDI));
When you create your instance, you pass a pointer to IDirectInputA, right? What pointer do you pass? If you pass an uninitialized or a null pointer, you will get undefined behavior.
TBH what you are trying to do is more complicated than you think. The problem arises in what exactly you are trying to do. Are you trying to wrap IDirectInputA OR are you trying to completely re-implement it.
If you are trying to wrap it do the following:
IDirectInputA* pDI = NULL;
HRESULT hr = _DirectInputCreateA( hinst, dwVersion, &pDI, NULL );
Then create your derived class as follows:
class xDirectInputA : public IDirectInputA
{
protected:
IDirectInputA* mpInternal;
public:
xDirectInputA( IDirectInputA* pInternal ) :
mpInternal( pInternal )
HRESULT CreateDevice( REFGUID rguid, IDirectInputDevice** ppDirectInputDevice, IUknown* pOuter )
{
// Do what ever processing you need.
return mpInternal->CreateDevice( rguid, ppDirectInputDevice, pOuter );
}
// Implement other functions.
};
Now you pass your xDirectInputA pointer around instead of the normal pointer returned from DirectInputCreate. You can now intercept every message that goes through the class.
If you are trying to do your own full re-implementation it is a LOT more complicated. You are going to need to fully implement the COM object. You'll be best off putting a DInput.DLL alongside the executable that contains your implementation. All in though this is only something you should try if you REALLY know what you are doing.
If you wish to learn COM fully I suggest purchasing Essential COM by Don Box. Its a VERY helpful book.
Lets say in a dialog, we dynamically create a variable number of CWnds... like creating a and registering a CButton every time the user does something/
Some pseudo-code...
class CMyDlg : public CDialog
{
vector<CWnd *> windows;
void onClick()
{
CButton *pButton = new CButton(...);
//do other stuff like position it here
windows.push_back(pButton);
}
}
Do I need to explicitly delete them or will MFC do it? If I have to, would it be in the destructor as normal, or are there any special things to avoid breaking MFC... making sure I don't delete the objects while the HWNDs are still in use for example?
CButton *pButton = new CButton(...);
These are C++ objects, which needs to be deleted explicitly. (Where as Main frame windows and Views are self destructed).
You can refer the detailed answer ( by me) Destroying Window Objects