You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
3.8 KiB
158 lines
3.8 KiB
14 years ago
|
/****************************************************************************
|
||
|
**
|
||
|
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
|
||
|
** Contact: Qt Software Information (qt-info.com)
|
||
|
**
|
||
|
** This file is part of a Qt Solutions component.
|
||
|
**
|
||
|
** Commercial Usage
|
||
|
** Licensees holding valid Qt Solutions licenses may use this file in
|
||
|
** accordance with the Qt Solutions Commercial License Agreement provided
|
||
|
** with the Software or, alternatively, in accordance with the terms
|
||
|
** contained in a written agreement between you and Nokia.
|
||
|
**
|
||
|
** If you are unsure which license is appropriate for your use, please
|
||
|
** contact the sales department at qt-sales.com.
|
||
|
**
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "qtsingleapplication.h"
|
||
|
#include <qt_windows.h>
|
||
|
#include <QtGui/QWidget>
|
||
|
|
||
|
class QtSingletonSysPrivate : public QWidget
|
||
|
{
|
||
|
public:
|
||
|
QtSingletonSysPrivate()
|
||
|
: QWidget(), listening(FALSE)
|
||
|
{
|
||
|
}
|
||
|
uint listening :1;
|
||
|
|
||
|
protected:
|
||
|
bool winEvent(MSG *msg, long *result)
|
||
|
{
|
||
|
if (msg->message != WM_COPYDATA)
|
||
|
return FALSE;
|
||
|
|
||
|
Q_ASSERT(msg->hwnd == winId());
|
||
|
COPYDATASTRUCT *data = (COPYDATASTRUCT*)msg->lParam;
|
||
|
QString message = QString::fromUtf16((unsigned short*)data->lpData);
|
||
|
|
||
|
emit ((QtSingleApplication*)qApp)->messageReceived( message );
|
||
|
|
||
|
if (result)
|
||
|
*result = 0;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
static HANDLE createLockedMutex(const QString &id)
|
||
|
{
|
||
|
HANDLE mutex;
|
||
|
QT_WA({
|
||
|
mutex = CreateMutex(0, FALSE, (TCHAR*)id.utf16());
|
||
|
}, {
|
||
|
mutex = CreateMutexA(0, FALSE, id.toLocal8Bit().data());
|
||
|
});
|
||
|
|
||
|
switch (WaitForSingleObject(mutex, INFINITE)) {
|
||
|
case WAIT_ABANDONED:
|
||
|
case WAIT_TIMEOUT:
|
||
|
CloseHandle(mutex);
|
||
|
mutex = 0;
|
||
|
break;
|
||
|
default: // WAIT_OBJECT_0
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return mutex;
|
||
|
}
|
||
|
|
||
|
static inline void closeLockedMutex(HANDLE handle)
|
||
|
{
|
||
|
if (!handle)
|
||
|
return;
|
||
|
|
||
|
ReleaseMutex(handle);
|
||
|
CloseHandle(handle);
|
||
|
}
|
||
|
|
||
|
static HWND findWindow(const QString &id)
|
||
|
{
|
||
|
HANDLE mutex = createLockedMutex(id);
|
||
|
|
||
|
HWND hwnd;
|
||
|
QString wid = id + "_QtSingleApplicationWindow";
|
||
|
|
||
|
QT_WA( {
|
||
|
hwnd = ::FindWindow(L"QWidget", (TCHAR*)wid.utf16());
|
||
|
}, {
|
||
|
hwnd = ::FindWindowA("QWidget", wid.toLocal8Bit().data());
|
||
|
} )
|
||
|
|
||
|
closeLockedMutex(mutex);
|
||
|
|
||
|
return hwnd;
|
||
|
}
|
||
|
|
||
|
void QtSingleApplication::sysInit()
|
||
|
{
|
||
|
sysd = new QtSingletonSysPrivate;
|
||
|
(void)sysd->winId(); // Force widget creation
|
||
|
}
|
||
|
|
||
|
void QtSingleApplication::sysCleanup()
|
||
|
{
|
||
|
HANDLE mutex = createLockedMutex(id());
|
||
|
|
||
|
delete sysd;
|
||
|
|
||
|
closeLockedMutex(mutex);
|
||
|
}
|
||
|
|
||
|
void QtSingleApplication::initialize( bool activate )
|
||
|
{
|
||
|
if (sysd->listening)
|
||
|
return;
|
||
|
|
||
|
HANDLE mutex = createLockedMutex(id());
|
||
|
|
||
|
sysd->listening = true;
|
||
|
sysd->setWindowTitle(id() + "_QtSingleApplicationWindow");
|
||
|
|
||
|
closeLockedMutex(mutex);
|
||
|
|
||
|
if ( activate )
|
||
|
connect(this, SIGNAL(messageReceived(const QString&)),
|
||
|
this, SLOT(activateWindow()));
|
||
|
}
|
||
|
|
||
|
bool QtSingleApplication::isRunning() const
|
||
|
{
|
||
|
return findWindow(id()) != 0;
|
||
|
}
|
||
|
|
||
|
bool QtSingleApplication::sendMessage( const QString &message, int timeout )
|
||
|
{
|
||
|
HWND hwnd = findWindow(id());
|
||
|
if ( !hwnd )
|
||
|
return FALSE;
|
||
|
|
||
|
COPYDATASTRUCT data;
|
||
|
data.dwData = 0;
|
||
|
data.cbData = (message.length()+1) * sizeof(QChar);
|
||
|
data.lpData = (void*)message.utf16();
|
||
|
DWORD result;
|
||
|
LRESULT res;
|
||
|
QT_WA( {
|
||
|
res = SendMessageTimeout(hwnd, WM_COPYDATA, 0/*hwnd sender*/, (LPARAM)&data,
|
||
|
SMTO_ABORTIFHUNG,timeout,&result);
|
||
|
}, {
|
||
|
res = SendMessageTimeoutA(hwnd, WM_COPYDATA, 0/*hwnd sender*/, (LPARAM)&data,
|
||
|
SMTO_ABORTIFHUNG,timeout,&result);
|
||
|
} )
|
||
|
return res != 0;
|
||
|
}
|