root/middleware-offline/trunk/_src/eidmw/eidgui/qtsingleapplication_win.cpp @ 5

Revision 5, 4.5 KB (checked in by vsilva, 9 years ago)

Initial comit

Line 
1/****************************************************************************
2**
3** Copyright (C) 2003-2007 Trolltech ASA. All rights reserved.
4**
5** This file is part of a Qt Solutions component.
6**
7** Licensees holding a valid Qt Solutions License Agreement may use this
8** file in accordance with the rights, responsibilities, and obligations
9** contained therein. Please consult your licensing agreement or contact
10** sales@trolltech.com if any conditions of this licensing are not clear
11** to you.
12**
13** Further information about Qt Solutions licensing is available at:
14** http://www.trolltech.com/products/qt/addon/solutions/
15** or by contacting info@trolltech.com.
16**
17** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19**
20****************************************************************************/
21#include "qtsingleapplication.h"
22#include <qt_windows.h>
23#include <QtGui/QWidget>
24
25class QtSingletonSysPrivate : public QWidget
26{
27public:
28    QtSingletonSysPrivate()
29        : QWidget(), listening(FALSE)
30    {
31    }
32    uint listening :1;
33
34protected:
35    bool winEvent(MSG *msg, long *result)
36    {
37        if (msg->message != WM_COPYDATA)
38            return FALSE;
39
40        Q_ASSERT(msg->hwnd == winId());
41        COPYDATASTRUCT *data = (COPYDATASTRUCT*)msg->lParam;
42        QString message = QString::fromUtf16((unsigned short*)data->lpData);
43
44        emit ((QtSingleApplication*)qApp)->messageReceived( message );
45
46                if (result)
47                {
48                        *result = 0;
49                        return TRUE;
50                }
51                return FALSE;
52    }
53
54};
55
56static HANDLE createLockedMutex(const QString &id)
57{
58    HANDLE mutex;
59    QT_WA({
60        mutex = CreateMutex(0, FALSE, (TCHAR*)id.utf16());
61    }, {
62       mutex = CreateMutexA(0, FALSE, id.toLocal8Bit().data());
63    });
64
65    switch (WaitForSingleObject(mutex, INFINITE)) {
66    case WAIT_ABANDONED:
67    case WAIT_TIMEOUT:
68        CloseHandle(mutex);
69        mutex = 0;
70        break;
71    default: // WAIT_OBJECT_0
72        break;
73    }
74
75    return mutex;
76}
77
78static inline void closeLockedMutex(HANDLE handle)
79{
80    if (!handle)
81        return;
82
83    ReleaseMutex(handle);
84    CloseHandle(handle);
85}
86
87static HWND findWindow(const QString &id)
88{
89    HANDLE mutex = createLockedMutex(id);
90
91    HWND hwnd;
92    QString wid = id + "_QtSingleApplicationWindow";
93        QString qwidget = "QWidget";
94
95    QT_WA( {
96        hwnd = ::FindWindowW(L"QWidget", (WCHAR*)wid.utf16());
97    }, {
98        hwnd = ::FindWindowA("QWidget", wid.toLocal8Bit().data());
99    } )
100
101    closeLockedMutex(mutex);
102
103    return hwnd;
104}
105
106void QtSingleApplication::sysInit()
107{
108    sysd = new QtSingletonSysPrivate;
109    (void)sysd->winId();                  // Force widget creation
110}
111
112void QtSingleApplication::sysCleanup()
113{
114    HANDLE mutex = createLockedMutex(id());
115
116    delete sysd;
117
118    closeLockedMutex(mutex);
119}
120
121void QtSingleApplication::initialize( bool activate )
122{
123    if (sysd->listening)
124        return;
125
126    HANDLE mutex = createLockedMutex(id());
127
128    sysd->listening = true;
129    sysd->setWindowTitle(id() + "_QtSingleApplicationWindow");
130
131    closeLockedMutex(mutex);
132
133    if ( activate )
134        connect(this, SIGNAL(messageReceived(const QString&)),
135                this, SLOT(activateWindow()));
136}
137
138bool QtSingleApplication::isRunning() const
139{
140    return findWindow(id()) != 0;
141}
142
143bool QtSingleApplication::sendMessage( const QString &message, int timeout )
144{
145    HWND hwnd = findWindow(id());
146    if ( !hwnd )
147        return FALSE;
148
149    COPYDATASTRUCT data;
150    data.dwData = 0;
151    data.cbData = (message.length()+1) * sizeof(QChar);
152    data.lpData = (void*)message.utf16();
153    DWORD result;
154    LRESULT res;
155    QT_WA( {
156        res = SendMessageTimeout(hwnd, WM_COPYDATA, 0/*hwnd sender*/, (LPARAM)&data,
157                                 SMTO_ABORTIFHUNG,timeout,(PDWORD_PTR)&result);
158    }, {
159        res = SendMessageTimeoutA(hwnd, WM_COPYDATA, 0/*hwnd sender*/, (LPARAM)&data,
160                                  SMTO_ABORTIFHUNG,timeout,(PDWORD_PTR)&result);
161    } )
162    //return res != 0;
163
164        // always return TRUE.
165        // The reason is that the main application can be processing for an undefined time.
166        // e.g. downloading and processing something.
167        // In that case, the timeout might trigger which is considered as a non responsive
168        // main application, while the app is just intensively processing.
169        // As a quick fix: if a window with the same ID exists, don't start a second instance
170        // regardless of the timeout for a response.
171
172        return TRUE;
173}
Note: See TracBrowser for help on using the browser.