Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: libertas от Март 10, 2014, 13:13



Название: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 10, 2014, 13:13
Всем привет!

Подскажите, пожалуйста, как мне отправить строку от родительского процесса дочернему при помощи WM_COPYDATA

В родительском процессе есть поле line edit и слот с обработкой:

Код:
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    HWND hChild = FindWindow(0, L"Child");
    HWND hParent = FindWindow(0, L"Parent");
    if ( hChild != 0)
    {
        wchar_t str[] = L"X";
        COPYDATASTRUCT data;
        data.cbData = sizeof(str);
        data.dwData = 33;
        data.lpData = str;
        SendMessage(hChild, WM_COPYDATA, (WPARAM)hParent, (LPARAM)&data);
    }else
        MessageBox(0, L"Cann't find window child", L"error", MB_OK);
}

У дочернего процесса такой обработчик:

Код:
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = static_cast<MSG*>(message);
    if(msg->message == WM_COPYDATA)
    {
       COPYDATASTRUCT* data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
       emit CopyData(QString((char*)data->lpData));
       result = 0;
       return true;
    }
    return false;
}

у дочернего процесса есть виджет qLabel.
Связь между главным окном главного окна и label  происходит при помощи:

connect(this, SIGNAL(CopyData(QString)), ui->label, SLOT(setText(QString)));

В итоге у меня появляется в label только буква 'X', а мне бы хотелось, чтоб в родительском процессе я ввел в Line edit строку и она отобразилась в label у дочернего процесса.

Как можно это сделать?

Спасибо.


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: gil9red от Март 10, 2014, 13:25
Код:
wchar_t str[] = L"X";
Так вы только строку "X" и отправляете :)


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 10, 2014, 15:13
согласен.  а как написать, чтоб работало?

Так тоже не работает:
Код:
wchar_t str[] = ui->lineEdit->text().toUtf8().data();


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: gil9red от Март 10, 2014, 17:24
Пример перевода QString в массив wchar_t  :)
Код:
wchar_t array[9];
QString processName = "test.exe";
processName.toWCharArray(array);


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 10, 2014, 18:01
Спасибо. Но у меня все равно пересылается только одна буква, и то первая, которую я ввожу в line edit...?


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: gil9red от Март 10, 2014, 18:04
Проверьте длину отправляемого сообщения и сколько принимаете, когда оно приходит :)


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 10, 2014, 22:07
Дебагер не останавливается на коде в дочернем процессе, там где происходит обработка моего сообения:

Код:
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = static_cast<MSG*>(message);
    if(msg->message == WM_COPYDATA)
    {
       COPYDATASTRUCT* data = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
       emit CopyData(QString((char*)data->lpData));
       result = 0;
       return true;
    }
    return false;
}

а в родительском происходит остановка после написания каждой буквы в line edit, при этом в переменной str[0], я не вижу самой буквы а вижу там только цифры в дебаггере.

Почему может не останавливаться дебагер в дочернем процессе и почему в str[0] в отладчике я не вижу буквы?(дебагер показывает аски код)?


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: Alex Custov от Март 11, 2014, 17:55
Код:
[quote author=libertas link=topic=26643.msg191680#msg191680 date=1394478420]
       emit CopyData(QString((char*)data->lpData));

Ты же отправляешь wchar*, а на принимающей стороне непонятно зачем преобразуешь в char*, причём сишным кастом.


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 12, 2014, 09:50
спасибо,

я переделал немного код:

Код:
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    HWND hChild = FindWindow(0, L"Child");
    if ( hChild != 0)
    {
        char* str = ui->lineEdit->text().toUtf8().data();
        COPYDATASTRUCT data;
        data.cbData = strlen(str);
        data.dwData = 33;
        data.lpData = str;
        SendMessage(hChild, WM_COPYDATA, reinterpret_cast<WPARAM>(winId()), reinterpret_cast<LPARAM>(&data));
    }else
        MessageBox(0, L"Cann't find window child", L"error", MB_OK);
}

Правда есть ещё одна проблема: во время пересылки появляются иероглифы к моим буквам. Нужно каким-то  образом обозначить пересылаемую строку символом конца строки '\0'?


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: Alex Custov от Март 12, 2014, 12:07
Правда есть ещё одна проблема: во время пересылки появляются иероглифы к моим буквам. Нужно каким-то  образом обозначить пересылаемую строку символом конца строки '\0'?

Ну да:

Цитировать
int QString::toWCharArray ( wchar_t * array ) const
...
Note: This function does not append a null character to the array.

Код
C++ (Qt)
char* str = ui->lineEdit->text().toUtf8().data();

так делать нельзя, при выходе из контекста вызова str будет указывать на неопределённые данные. Учи С++. Рабочий пример уже дали - используй toWCharArray и пересылай данные в формате wchar*


Название: Re: отправка сообщения при помощи WM_COPYDATA
Отправлено: libertas от Март 12, 2014, 12:32
спасибо большое.