做个笔记:
在windows系统,定制一个小工具,并设计成单例进程,每次调用的时候避免出现多个进程实例,而且每次调用,激活已经打开的工具进程,并把它激活到置顶到屏幕上,遇到在win10的环境下工具进程单纯调用activeWindow只是会在任务栏闪几下,没有真正激活到屏幕上,所以要做一个小小的处理,如下代码所示:
声明一个系统内部api
typedef void (WINAPI* PROCSWITCHTOTHISWINDOW)(HWND, BOOL);
bool mainwindow::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
if (msg->message == WM_COPYDATA) {
// extract the string from lParam
COPYDATASTRUCT* data = (COPYDATASTRUCT*)msg->lParam;
if (data) {
char* buf = new char[64];
memset(buf, 0, 64);
memcpy(buf, data->lpData, data->cbData);
if (strcmp(buf, "activeWnd") == 0)
{
activateWindow();
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
raise();//必须加,不然X11会不起作用
#ifdef Q_OS_WIN32
HWND hWnd = (HWND)winId();
PROCSWITCHTOTHISWINDOW SwitchToThisWindow = NULL;
HMODULE hUser32 = GetModuleHandle(TEXT("user32"));
SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, "SwitchToThisWindow");
if (SwitchToThisWindow) {
SwitchToThisWindow(hWnd, TRUE);
}
#endif //Q_OS_WIN32
}
delete[]buf;
return true;
}
}
return QWidget::nativeEvent(eventType, message, result);
}
还有另外一种方法:
activateWindow();
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
raise();//必须加,不然X11会不起作用
#ifdef Q_OS_WIN32 //windows必须加这个,不然windows10 会不起作用,具体参看activateWindow 函数的文档
HWND hForgroundWnd = GetForegroundWindow();
DWORD dwForeID = ::GetWindowThreadProcessId(hForgroundWnd, NULL);
DWORD dwCurID = ::GetCurrentThreadId();
::AttachThreadInput(dwCurID, dwForeID, TRUE);
::SetForegroundWindow((HWND)winId());xcsc_jnx
::AttachThreadInput(dwCurID, dwForeID, FALSE);
#endif // Q_OS_WIN32