linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06374
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3162: allow DWT to be used in a shared library
------------------------------------------------------------
revno: 3162
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2012-12-27 14:37:10 +0100
message:
allow DWT to be used in a shared library
added:
dwt/Preprocessor macros.txt
modified:
dwt/include/dwt/Application.h
dwt/src/Application.cpp
dwt/src/Dispatcher.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
=== added file 'dwt/Preprocessor macros.txt'
--- dwt/Preprocessor macros.txt 1970-01-01 00:00:00 +0000
+++ dwt/Preprocessor macros.txt 2012-12-27 13:37:10 +0000
@@ -0,0 +1,20 @@
+This document lists preprocessor macros available to tweak the way DWT is built.
+
+--- Important ---
+
+DWT_SHARED: Define when DWT is meant to be used in a shared library, rather than in a main
+application.
+When DWT_SHARED is defined, the implementor is expected to call dwt::Application::init
+and dwt::Application::uninit. It is assumed the host of the library will be pumping messages; so no
+message loop is provided under DWT_SHARED.
+When DWT_SHARED is not defined, the implementor is expected to provide the dwtMain function which
+DWT calls and which should launch the message loop by calling dwt::Application::run.
+Note that a few features of DWT have limited availability under DWT_SHARED; notably:
+- Asynchronous calls (set by dwt::Application::callAsync or dwt::Widget::callAsync) are synchronous
+(because the shared library can't inject its asynchronous calls into its host's message pump).
+- Accelerator keys aren't handled (for similar reasons).
+
+--- Debugging ---
+
+DWT_DEBUG_WIDGETS: Define to write debugging messages to standard output whenever a widget is
+created or destroyed. This is useful to track widget leaks.
=== modified file 'dwt/include/dwt/Application.h'
--- dwt/include/dwt/Application.h 2012-09-21 18:35:34 +0000
+++ dwt/include/dwt/Application.h 2012-12-27 13:37:10 +0000
@@ -74,7 +74,9 @@
*/
class Application :public boost::noncopyable
{
+#ifndef DWT_SHARED
static int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
+#endif
friend class Widget;
public:
@@ -139,7 +141,7 @@
/// The initialization that must be done first.
/** Used internally by the WinMain function, and externally for DLL initialization.
*/
- static void init( int nCmdShow );
+ static void init();
/// Shut down operations
static void uninit();
@@ -152,6 +154,7 @@
const CommandLine & getCommandLine() const;
int getCmdShow() const;
+ void setCmdShow(int cmdShow);
/// Adds a waitable event HANDLE and the according signal
/** You can feed in here HANDLEs of thread handles, console inputs, mutexes,
@@ -198,7 +201,7 @@
DWORD threadId;
// Private Constructor to ensure Singleton Implementation
- Application( int nCmdShow );
+ Application();
~Application();
=== modified file 'dwt/src/Application.cpp'
--- dwt/src/Application.cpp 2012-12-21 22:50:48 +0000
+++ dwt/src/Application.cpp 2012-12-27 13:37:10 +0000
@@ -41,8 +41,6 @@
#include <dwt/widgets/Control.h>
#include <assert.h>
-extern int dwtMain(dwt::Application& app);
-
namespace dwt {
Application* Application::itsInstance = 0;
@@ -53,8 +51,8 @@
/** Initializes the runtime for SmartWin++
Typically only called by WinMain or DllMain.
*/
-void Application::init(int nCmdShow) {
- itsInstance = new Application(nCmdShow);
+void Application::init() {
+ itsInstance = new Application();
BOOL enable;
if(::SystemParametersInfo(SPI_GETUIEFFECTS, 0, &enable, 0) && !enable) {
@@ -73,8 +71,8 @@
::InitCommonControlsEx(&init);
}
-Application::Application(int nCmdShow) :
- itsCmdShow(nCmdShow),
+Application::Application() :
+ itsCmdShow(0),
tasks(1024),
quit(false),
threadId(::GetCurrentThreadId())
@@ -223,6 +221,10 @@
return itsCmdShow;
}
+void Application::setCmdShow(int cmdShow) {
+ itsCmdShow = cmdShow;
+}
+
bool Application::dispatchAsync() {
Callback callback;
if(tasks.pop(callback)) {
@@ -232,11 +234,22 @@
return false;
}
+#ifndef DWT_SHARED
+
void Application::callAsync(const Callback& callback) {
tasks.push(callback);
wake();
}
+#else
+
+// async calls don't work when we aren't in charge of the message loop - run them synchronously.
+void Application::callAsync(const Callback& callback) {
+ callback();
+}
+
+#endif
+
Application::FilterIter Application::addFilter(const FilterFunction& f) {
return filters.insert(filters.end(), f);
}
@@ -247,13 +260,19 @@
} // namespace dwt
+#ifndef DWT_SHARED
+
+extern int dwtMain(dwt::Application& app);
+
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- dwt::Application::init(nCmdShow);
+ dwt::Application::init();
auto hr = ::OleInitialize(nullptr);
if(FAILED(hr))
return hr;
+ dwt::Application::instance().setCmdShow(nCmdShow);
+
int ret = dwtMain(dwt::Application::instance()); // Call library user's startup function.
::OleUninitialize();
@@ -262,3 +281,5 @@
return ret;
}
+
+#endif
=== modified file 'dwt/src/Dispatcher.cpp'
--- dwt/src/Dispatcher.cpp 2012-11-05 20:39:11 +0000
+++ dwt/src/Dispatcher.cpp 2012-12-27 13:37:10 +0000
@@ -220,7 +220,13 @@
std::basic_stringstream<TCHAR> stream;
stream << name.c_str();
- classNames.push_back(stream.str());
+#ifdef DWT_SHARED
+ /* in a shared library, classes registered by the lib can't clash with those regged by the host
+ or by other dynamically loaded libs. append a (hopefully unique) string to that end... */
+ stream << &Application::instance();
+#endif
+
+ classNames.push_back(move(stream.str()));
return classNames.back().c_str();
}