I have found the reason:
window_service_impl_t does not delete, but calls DestroyWindow() instead, im now researching about CWindowImpl
Edit:
Okay, normally , if using CWindowImpl, one would free/destruct on the DestroyWindow() call.
However, as my window is not using CWindowImpl, and i just relayed all messages from CWindowImpl to it, I decided to no longer inherit from CWindowImpl.
However, I still wanted to use ui_element_impl_withpopup from the ATLHelpers, so I have stripped all ATL code from these templates (all but the usage of CFlashWindow).
Modified code follows, in case somebody finds this useful.
template<typename TImpl, typename TInterface = ui_element> class my_ui_element_impl : public TInterface {
public:
GUID get_guid() { return TImpl::g_get_guid();}
GUID get_subclass() { return TImpl::g_get_subclass();}
void get_name(pfc::string_base & out) { TImpl::g_get_name(out); }
ui_element_instance::ptr instantiate(HWND parent,ui_element_config::ptr cfg,ui_element_instance_callback::ptr callback) {
PFC_ASSERT( cfg->get_guid() == get_guid() );
service_nnptr_t<ui_element_instance_impl_helper> item = new service_impl_t<ui_element_instance_impl_helper>(cfg,callback);
item->initialize_window(parent);
return item;
}
ui_element_config::ptr get_default_configuration() { return TImpl::g_get_default_configuration(); }
ui_element_children_enumerator_ptr enumerate_children(ui_element_config::ptr cfg) {return NULL;}
bool get_description(pfc::string_base & out) {out = TImpl::g_get_description(); return true;}
private:
class ui_element_instance_impl_helper : public TImpl {
public:
ui_element_instance_impl_helper(ui_element_config::ptr cfg, ui_element_instance_callback::ptr callback) : TImpl(cfg,callback) {}
GUID get_guid() {return TImpl::g_get_guid();}
GUID get_subclass() {return TImpl::g_get_subclass();}
HWND get_wnd() {return TImpl::get_wnd();}
};
public:
typedef ui_element_instance_impl_helper TInstance;
static TInstance const & instanceGlobals() {return *reinterpret_cast<const TInstance*>(NULL);}
};
template<typename TClass>
class my_ImplementBumpableElem : public TClass {
private:
typedef my_ImplementBumpableElem<TClass> TSelf;
public:
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(my_ImplementBumpableElem, TClass, {_init();} )
void notify(const GUID & p_what, t_size p_param1, const void * p_param2, t_size p_param2size) {
if (p_what == ui_element_notify_visibility_changed && p_param2 == 0 && m_flash.m_hWnd != NULL) m_flash.Deactivate();
__super::notify(p_what, p_param1, p_param2, p_param2size);
}
static bool Bump() {
for(pfc::const_iterator<TSelf*> walk = instances.first(); walk.is_valid(); ++walk) {
if ((*walk)->_bump()) return true;
}
return false;
}
~my_ImplementBumpableElem() throw() {
PFC_ASSERT(core_api::is_main_thread());
m_selfDestruct = true;
m_flash.CleanUp();
instances -= this;
}
private:
bool _bump() {
if (m_selfDestruct || m_hWnd == NULL) return false;
//PROBLEM: This assumes we're implementing service_base methods at this point. Explodes if called during constructors/destructors.
if (!this->m_callback->request_activation(this)) return false;
m_flash.Activate(m_hWnd);
return true;
}
void _init() {
m_selfDestruct = false;
PFC_ASSERT(core_api::is_main_thread());
instances += this;
}
static pfc::avltree_t<TSelf*> instances;
bool m_selfDestruct;
CFlashWindow m_flash;
};
template<typename TImpl, typename TInterface = ui_element_v2> class my_ui_element_impl_withpopup : public my_ui_element_impl<my_ImplementBumpableElem<TImpl>, TInterface> {
public:
t_uint32 get_flags() {return KFlagHavePopupCommand | KFlagSupportsBump;}
bool bump() {return my_ImplementBumpableElem<TImpl>::Bump();}
};
template<typename TClass>
pfc::avltree_t<my_ImplementBumpableElem<TClass> *> my_ImplementBumpableElem<TClass>::instances;
static service_factory_t<my_ui_element_impl_withpopup<uie_lyrics_dui> > g_ui_element_myimpl_factory;