| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- #include "ccnotepad.h"
- #include "jsondeploy.h"
- #include "styleset.h"
- #include <QtWidgets/QApplication>
- #include <QTextCodec>
- #include <QMessageBox>
- #include <QSharedMemory>
- #include <QFile>
- #include <QStatusBar>
- #include <qobject.h>
- #include <QThread>
- #include <QDir>
- #ifdef Q_OS_UNIX
- #include <QStyleFactory>
- #include <signal.h>
- #include <unistd.h>
- #include <QDebug>
- #include <QWidget>
- #endif
- #ifdef Q_OS_WIN
- #pragma comment(lib, "user32.lib")
- #include <qt_windows.h>
- const ULONG_PTR CUSTOM_TYPE = 10000;
- const ULONG_PTR OPEN_NOTEPAD_TYPE = 10001;
- bool s_isAdminAuth = false;
- #endif
- const QString c_strTitle = "notepad--";
- #ifdef Q_OS_UNIX
- #if defined(Q_OS_MAC)
- QSharedMemory shared("CCNotebook116");;//mac下面后面带一个版本号,避免新的打不开
- #else
- QSharedMemory shared("CCNotebook");
- #endif
- QSharedMemory nppShared("notepad--");
- static void sig_usr(int signo)
- {
- if(signo == SIGUSR1)
- {
- qlonglong winId;
- shared.lock();
- memcpy(&winId,shared.data(),sizeof(qlonglong));
- shared.unlock();
- QWidget *pMain = QWidget::find((WId)winId);
- CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);
- if(pNotePad != nullptr)
- {
- QString filePath((char*)nppShared.data()+4);
- if(!filePath.isEmpty())
- {
- pNotePad->openFile(filePath);
- }
- pNotePad->activateWindow();
- pNotePad->showNormal();
- qDebug() << "sig_usr" << filePath;
- }
- }
- }
- #endif
- #ifdef Q_OS_MAC
- static void openfile(QString filePath)
- {
- qlonglong winId;
- shared.lock();
- memcpy(&winId,shared.data(),sizeof(qlonglong));
- shared.unlock();
- QWidget *pMain = QWidget::find((WId)winId);
- CCNotePad* pNotePad = dynamic_cast<CCNotePad*>(pMain);
- if(pNotePad != nullptr)
- {
- if(!filePath.isEmpty())
- {
- pNotePad->openFile(filePath);
- }
- pNotePad->activateWindow();
- pNotePad->showNormal();
- }
- }
- class MyApplication : public QApplication
- {
- public:
- MyApplication(int &argc, char **argv)
- : QApplication(argc, argv)
- {
- }
- bool event(QEvent *event)
- {
- if (event->type() == QEvent::FileOpen) {
- QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
- qDebug() << "Open file" << openEvent->file();
- s_openfile = openEvent->file();
- openfile(s_openfile);
- }
- return QApplication::event(event);
- }
- QString s_openfile;
- };
- #endif
- int main(int argc, char *argv[])
- {
- #ifdef Q_OS_MAC
- MyApplication a(argc, argv);
- #else
- QApplication a(argc, argv);
- #endif
- QDir::setCurrent(QCoreApplication::applicationDirPath());
- #if defined(Q_OS_UNIX)
- QApplication::setStyle(QStyleFactory::create("fusion"));
- #endif
- a.setApplicationDisplayName(c_strTitle);
- a.setApplicationName(c_strTitle);
- QStringList arguments = QCoreApplication::arguments();
- #ifdef Q_OS_WIN
- QSharedMemory shared("ccnotepad");
- if (arguments.size() > 2)
- {
- //如果是多开请求,这种是从管理员权限申请后重开过来的
- if (arguments[1] == QString("-muti"))
- {
- s_isAdminAuth = true;
- QString title = QString(u8"%1 管理员").arg(c_strTitle);
- a.setApplicationDisplayName(title);
- //删除-muti这个参数
- arguments.removeAt(1);
-
- //管理员不占用共享标志。这样的目的是,当管理员窗口存在时
- //打开原来的文件,原来的文件可以占用共享标志,作为主窗口打开。
- //管理员窗口永远不做主窗口打开
- goto authAdmin;
-
- }
- }
- #endif
- //attach成功表示已经存在该内存了,表示当前存在实例
- if (shared.attach())//共享内存被占用则直接返回
- {
- //发现在文件中如果存在空格时,参数不止1个,所以不能单纯用2个参数表示
- if (arguments.size() > 1)
- {
- #if defined(Q_OS_WIN)
- qlonglong hwndId;
- shared.lock();
- memcpy(&hwndId, shared.data(), sizeof(qlonglong));
- shared.unlock();
- HWND hwnd = (HWND)hwndId;
- if (::IsWindow(hwnd))
- {
- //去掉第一个参数,后续的参数拼接起来。其实参数中间有空格还是需要使用""引用起来,避免空格参数分隔为多个
- arguments.takeFirst();
- QString filename = arguments.join("");
- QByteArray data = filename.toUtf8();
- COPYDATASTRUCT copydata;
- copydata.dwData = CUSTOM_TYPE; //自定义类型
- copydata.lpData = data.data(); //数据大小
- copydata.cbData = data.size(); // 指向数据的指针
- ::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(©data));
- }
- else
- {
- //失败了,此时说明前一个窗口极可能状态错误了。如果不处理,则再也打不开程序了
- goto drop_old;
- }
- #elif defined (Q_OS_MAC)
- {
- //mac下面不需要,有他自身的机制保证
- }
- #else
- pid_t pid;
- arguments.takeFirst();
- QString filename = arguments.join("");
- QByteArray data = filename.toUtf8();
- nppShared.attach();
- nppShared.lock();
- memcpy(&pid, nppShared.data(), sizeof(pid_t));
- memset((char*)nppShared.data()+sizeof(pid_t),0, 1024-sizeof(pid_t));
- memcpy((char*)nppShared.data()+sizeof(pid_t),data.data(),data.size());
- nppShared.unlock();
- kill(pid,SIGUSR1);
- #endif
- }
- else if (arguments.size() == 1)
- {
- #if defined(Q_OS_WIN)
- //把窗口设置到最前
- qlonglong hwndId;
- shared.lock();
- memcpy(&hwndId, shared.data(), sizeof(qlonglong));
- shared.unlock();
- HWND hwnd = (HWND)hwndId;
- if (::IsWindow(hwnd))
- {
- QString filename("open");
- QByteArray data = filename.toUtf8();
- COPYDATASTRUCT copydata;
- copydata.dwData = OPEN_NOTEPAD_TYPE; //自定义类型
- copydata.lpData = data.data(); //数据大小
- copydata.cbData = data.size(); // 指向数据的指针
- ::SendMessage(hwnd, WM_COPYDATA, reinterpret_cast<WPARAM>(nullptr), reinterpret_cast<LPARAM>(©data));
- }
- else
- {
- //失败了,此时说明前一个窗口极可能状态错误了。如果不处理,则再也打不开程序了
- //继续新开一个窗口,放弃之前的旧内容
- goto drop_old;
- }
- #elif defined (Q_OS_MAC)
- {
- //mac下面不需要,有他自身的机制保证
- }
- #else
- pid_t pid;
- nppShared.attach();
- nppShared.lock();
- memcpy(&pid, nppShared.data(), sizeof(pid_t));
- memset((char*)nppShared.data()+sizeof(pid_t),0, 1024-sizeof(pid_t));
- nppShared.unlock();
- qDebug()<<"empty file send";
- kill(pid,SIGUSR1);
- #endif
- }
- return 0;
- }
- #if defined(Q_OS_WIN)
- shared.create(32);
- #elif defined (Q_OS_MAC)
- {
- //mac下面不需要,有他自身的机制保证。当程序已经在线时,再打开程序,系统会自动调用已经存在的程序出现
- //不需要使用类似linux下面的机制。
- shared.create(32);
- nppShared.create(32);
- }
- #else
- shared.create(32);
- nppShared.create(2048);
- if(signal(SIGUSR1,sig_usr) == SIG_ERR)
- {
- qDebug()<<"linux create sign failed";
- }
- #endif
- #if defined(Q_OS_WIN)
- authAdmin:
- drop_old:
- #endif
- //20221009发现有小概率出现窗口没有,但是进程还在的诡异问题,加个保护一下
- QApplication::setQuitOnLastWindowClosed(true);
- JsonDeploy::init();
- int id = JsonDeploy::getKeyValueFromNumSets(SKIN_KEY);
- StyleSet::setSkin(id);
- CCNotePad *pMainNotepad = new CCNotePad(true);
- pMainNotepad->setAttribute(Qt::WA_DeleteOnClose);
- pMainNotepad->setShareMem(&shared);
- pMainNotepad->show();
- pMainNotepad->syncCurSkinToMenu(id);
- #ifdef uos
- QFont font("Noto Sans CJK JP,9,-1,5,50,0,0,0,0,0,Regular", 9);
- QApplication::setFont(font);
- #endif
- #ifdef Q_OS_MAC
- //这里的字体大小,务必要和查找结果框的高度匹配,否则会结构字体拥挤
- QFont font("Courier New,11,-1,5,50,0,0,0,0,0,Regular", 11);
- QApplication::setFont(font);
- #endif
- #ifdef Q_OS_WIN
- //HWND hwnd = ::FindWindowA("Qt5QWindowIcon", "CCNotebook");
- //发现hwnd就是和effectiveWinId相等的,不需要查询了
- //管理员可以多开,暂时不把管理员的权限作为主窗口,因为其他用户没有权限右键菜单发送消息给管理员窗口去打开文件
- if (!s_isAdminAuth)
- {
- qlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();
- shared.lock();
- memcpy(shared.data(), &winId, sizeof(qlonglong));
- shared.unlock();
- }
- #else
- qlonglong winId = (qlonglong)pMainNotepad->effectiveWinId();
- shared.lock();
- memcpy(shared.data(), &winId, sizeof(qlonglong));
- shared.unlock();
- nppShared.attach();
- //get proceess id to share memory
- pid_t pid = getpid();
- nppShared.lock();
- memcpy(nppShared.data(), &pid, sizeof(pid_t));
- nppShared.unlock();
- #endif // Q_OS_WIN
- //else
- //{
- // pMainNotepad->initTabNewOne();
- //}
- //恢复上次关闭时的文件
- #ifdef Q_OS_WIN
- if (!s_isAdminAuth)
- {
- if (0 == pMainNotepad->restoreLastFiles())
- {
- pMainNotepad->initTabNewOne();
- }
- }
- #else
- if (0 == pMainNotepad->restoreLastFiles())
- {
- pMainNotepad->initTabNewOne();
- }
- #endif
- if (arguments.size() == 2)
- {
- pMainNotepad->openFile(arguments[1]);
- pMainNotepad->showNormal();
- }
- #ifdef Q_OS_WIN
- pMainNotepad->checkAppFont();
- #endif
- a.exec();
- JsonDeploy::close();
- return 0;
- }
|