linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06317
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3146: fix leaks related to combo boxes differently
------------------------------------------------------------
revno: 3146
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Tue 2012-11-27 21:54:06 +0100
message:
fix leaks related to combo boxes differently
modified:
dwt/include/dwt/Widget.h
dwt/include/dwt/WidgetCreator.h
dwt/src/Widget.cpp
dwt/src/widgets/ComboBox.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dwt/include/dwt/Widget.h'
--- dwt/include/dwt/Widget.h 2012-11-25 18:27:27 +0000
+++ dwt/include/dwt/Widget.h 2012-11-27 20:54:06 +0000
@@ -165,9 +165,8 @@
/**
* Attaches the instance to an existing window.
- * @return the previous window proc, if there was one.
*/
- WNDPROC setHandle(HWND hwnd);
+ void setHandle(HWND hwnd);
/// get the top-most parent window of this widget (either a main window or a modal dialog).
Widget* getRoot() const;
=== modified file 'dwt/include/dwt/WidgetCreator.h'
--- dwt/include/dwt/WidgetCreator.h 2012-11-25 18:27:27 +0000
+++ dwt/include/dwt/WidgetCreator.h 2012-11-27 20:54:06 +0000
@@ -85,9 +85,7 @@
static typename WidgetType::ObjectType attach(Widget* parent, HWND hwnd)
{
typename WidgetType::ObjectType w(new WidgetType(parent));
- auto proc = w->setHandle(hwnd);
- // "detach" from the window before the parent is destroyed.
- parent->onDestroy([=] { ::SetWindowLongPtr(w->handle(), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc)); w->kill(); });
+ w->setHandle(hwnd);
return w;
}
};
=== modified file 'dwt/src/Widget.cpp'
--- dwt/src/Widget.cpp 2012-11-25 18:27:27 +0000
+++ dwt/src/Widget.cpp 2012-11-27 20:54:06 +0000
@@ -55,16 +55,27 @@
GlobalAtom Widget::propAtom(_T("dwt::Widget*"));
+#ifdef _DEBUG
+int widgetCount;
+#endif
+
Widget::Widget(Widget* parent_, Dispatcher& dispatcher_) :
hwnd(NULL), parent(parent_), dispatcher(dispatcher_)
{
-
+#ifdef _DEBUG
+ ++widgetCount;
+ printf("created a dwt widget; count: %d\n", widgetCount);
+#endif
}
Widget::~Widget() {
if(hwnd) {
::RemoveProp(hwnd, propAtom);
}
+#ifdef _DEBUG
+ --widgetCount;
+ printf("destroying a dwt widget; count: %d\n", widgetCount);
+#endif
}
void Widget::kill() {
@@ -84,7 +95,7 @@
return hWnd;
}
-WNDPROC Widget::setHandle(HWND h) {
+void Widget::setHandle(HWND h) {
if(hwnd) {
throw DWTException("You may not attach to a widget that's already attached");
}
@@ -93,7 +104,7 @@
::SetProp(hwnd, propAtom, reinterpret_cast<HANDLE>(this));
- return reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowProc::wndProc)));
+ ::SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WindowProc::wndProc));
}
Widget* Widget::getRoot() const {
=== modified file 'dwt/src/widgets/ComboBox.cpp'
--- dwt/src/widgets/ComboBox.cpp 2012-11-25 18:27:27 +0000
+++ dwt/src/widgets/ComboBox.cpp 2012-11-27 20:54:06 +0000
@@ -76,8 +76,15 @@
ComboBox::DropListBoxPtr ComboBox::getListBox() {
if(!listBox) {
COMBOBOXINFO info = { sizeof(COMBOBOXINFO) };
- if(::GetComboBoxInfo(handle(), &info) && info.hwndList && info.hwndList != handle())
+ if(::GetComboBoxInfo(handle(), &info) && info.hwndList && info.hwndList != handle()) {
+ /* unlike other controls, the list window doesn't send/receive WM_DESTROY/WN_NCDESTROY.
+ as a result, the listBox widget leaks. the workaround is to "detach" from the list (by
+ giving it back its initial window procedure) when the combo is being destroyed. */
+ auto proc = ::GetWindowLongPtr(info.hwndList, GWLP_WNDPROC);
listBox = WidgetCreator<DropListBox>::attach(this, info.hwndList);
+ listBox->onDestroy([this] { listBox = nullptr; });
+ onDestroy([this, proc] { if(listBox) { ::SetWindowLongPtr(listBox->handle(), GWLP_WNDPROC, proc); listBox->kill(); } });
+ }
}
return listBox;
}
@@ -85,8 +92,14 @@
TextBoxPtr ComboBox::getTextBox() {
if(!textBox) {
COMBOBOXINFO info = { sizeof(COMBOBOXINFO) };
- if(::GetComboBoxInfo(handle(), &info) && info.hwndItem && info.hwndItem != handle())
+ if(::GetComboBoxInfo(handle(), &info) && info.hwndItem && info.hwndItem != handle()) {
+ /* combo edits do receive destruction messages, but we do the same crap as for lists
+ to be on the safe side. */
+ auto proc = ::GetWindowLongPtr(info.hwndItem, GWLP_WNDPROC);
textBox = WidgetCreator<TextBox>::attach(this, info.hwndItem);
+ textBox->onDestroy([this] { textBox = nullptr; });
+ onDestroy([this, proc] { if(textBox) { ::SetWindowLongPtr(textBox->handle(), GWLP_WNDPROC, proc); textBox->kill(); } });
+ }
}
return textBox;
}