QT实现只允许运行一个程序实例

共享内存 + 进程间通信 + 发Windows消息方式 + 只允许打开一个窗体

  • main.cpp
// 共享内存的key
    const char *key = "My test client shared memory key";
    QSharedMemory sharedMem(key);
    // 只能运行一个实例
    if (!sharedMem.create(strlen(key)))
    {
        qDebug("has already run one program");
        const QString title = ClientName;
        LPWSTR client = (LPWSTR)title.utf16();
        HWND hwnd = ::FindWindowW(NULL, client);
        if(::IsWindow(hwnd))
        {
            // 使用进程通信,发送Windows消息打开已启动实例的窗口
            COPYDATASTRUCT copydata;
            copydata.dwData = CUSTOM_TYPE;
            QByteArray data =  QStringLiteral(ClientName).toUtf8();
            copydata.lpData = data.data();  //数据大小
            copydata.cbData = data.size();  // 指向数据的指针
            HWND sender = 0;
            qDebug("reshow the window");
            ::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(sender), reinterpret_cast<LPARAM>(&copydata));
        }
        qDebug("exit...");
        return 0;
    }

  • MainWindow.cpp
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG *param = static_cast<MSG *>(message);

    switch (param->message)
    {
    case WM_COPYDATA:
    {
        COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT*>(param->lParam);
        if (cds->dwData == CUSTOM_TYPE)
        {
            qDebug("receive reshow window message");
            setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);
            showNormal();
            qDebug("the window has been reshowed");
            return true;
        }
        break;
    }
    default:
        break;
    }

    return QWidget::nativeEvent(eventType, message, result);
}

猜你喜欢

转载自blog.csdn.net/m0_37406679/article/details/79364302
今日推荐