powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / отправка сообщений между процессами WM_COPYDATA
19 сообщений из 19, страница 1 из 1
отправка сообщений между процессами WM_COPYDATA
    #38582788
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте,

столкнулся с проблемой при отправке сообщений при помощи wm_copydata

У меня есть родительский процесс, у которого есть line edit. Есть дочерний процесс, у дочернего процесса есть label. Задача, чтоб при написании текста в line edit он отобразился в дочернем процессе в поле label.

Вот мой код у родителя:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
void MainWindow::on_lineEdit_textChanged(const QString &arg1)
{
    HWND hChild = FindWindow(0, L"Child");
    if ( hChild != 0)
    {
        wchar_t arr[10];
        QString str = ui->lineEdit->text();
        str.toWCharArray(arr);
        COPYDATASTRUCT data;
        data.cbData = sizeof(str);
        data.dwData = 33;
        data.lpData = arr;
        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);
}



здесь я использую слот textChanged()

Вот код у дочернего процесса:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this, SIGNAL(CopyData(QString)), ui->label, SLOT(setText(QString)));
}
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = static_cast<MSG*>(message);
    static UINT m = RegisterWindowMessage(L"MyMessage");
    if(msg->message == WM_COPYDATA)
    {
       COPYDATASTRUCT* pdata = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
       if (pdata->dwData == 33)
       emit CopyData(QString((char*)pdata->lpData));
       *result = 0;
       return true;
    }
    return false;
}



Но когда я ввожу в line edit в родителе строку в дочернем процессе появляется только одна буква(самая первая, которую ввел в родительском процессе).

Почему может так получаться?

Спасибо.
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38582872
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtus,

Это
Код: plaintext
1.
data.cbData = sizeof(str);



очевидно неверно.
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38582914
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
emit CopyData(QString((char*)pdata->lpData));

а вместо char* не wchar_t* должен быть?
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38582930
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtusПочему может так получаться?
Потому что какой-то диверсант перед отправкой перевёл char* в WCharArray.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583048
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_Sla, если делать с wchar_t*, то ругается компилятор:

" error: conversion from 'wchar_t*' to 'QChar' is ambiguous
emit CopyData(QString((wchar_t*)pdata->lpData)); "
^
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583061
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, спасибо!

Переписал немного код родителя:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
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 = sizeof(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);
}



Так стали отправляються буквы, но только 4, после четырех букв появляются либо иероглифы, либо пусто. Больше нельзя отправлять, либо где-то ошибка?
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583063
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, а почему тут ошибка?

Вот я поправил немного код:

Код: plaintext
1.
2.
3.
4.
5.
char* str = ui->lineEdit->text().toUtf8().data();
        COPYDATASTRUCT data;
        data.cbData = sizeof(str);
        data.dwData = 33;
        data.lpData = str;



и получается, что только я напечатал букву она пересылается дочернему потоку.
и размер буквы равен размеру char. Или в данном коде уже так нормально?
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583084
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtusстали отправляються буквы, но только 4
Угадай с трёх раз sizeof(char*), чудик.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583092
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, спасибо Вам большое=). И правда sizeof(char*) = 4 байта и поэтому отправляются 4 буквы=)
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583177
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtusMasterZiv, а почему тут ошибка?

Вот я поправил немного код:

Код: plaintext
1.
2.
3.
4.
5.
char* str = ui->lineEdit->text().toUtf8().data();
        COPYDATASTRUCT data;
        data.cbData = sizeof(str);
        data.dwData = 33;
        data.lpData = str;



и получается, что только я напечатал букву она пересылается дочернему потоку.
и размер буквы равен размеру char. Или в данном коде уже так нормально?


Потому что должно быть что-то типа

Код: plaintext
1.
data.cbData = strlen(str);
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583457
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtus,
чтоб ты там не делал
ты должен понимать что
data.lpData -это указатель на ячейку памяти, начиная с которой у тебя лежит твое слово
А слово состоит из буков. 1 буква=1байт (0-255) - по крайней мере в ansi
Причем когда ты пишешь эти байты в память например
С Л О В О - 5 букв, ты должен дописать 6-й байт /0 (0)
И data.cbData у тебя в этом случае =6 (но в любом случае не меньше 6) - это твоя так сказать гарантия что эти 6 байт не сотрутся из памяти, пока другая сторона их не прочитает и не вернет результат на SendMessage в посылающее приложение.
Если напишешь 4, то больше 4 байтов скорее всего не прочтешь.
И кстати, на принимающей стороне, если ты не забываешь писать 0-байт на конце, то на data.cbData можешь не обращать внимание вообще, а тупо читать байты из памяти data.lpData, data.lpData+1, data.lpData+2, пока не уткнешься в завершающий \0 -это и будет конец твоего слова.
Просто когда в VB6 я начинал с этим работать, у меня были точно такие проблемы, пока я не осознал как это работает и не написал 2 ф-ции: 1) которая кладет байты + \0 и возвращает адрес памяти 2) которая читает байты начиная с этого адреса вплоть до \0. С тех пор проблем нет.
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583505
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtusm_Sla, если делать с wchar_t*, то ругается компилятор:

" error: conversion from 'wchar_t*' to 'QChar' is ambiguous
emit CopyData(QString((wchar_t*)pdata->lpData)); "
^тогда так
Код: plaintext
1.
emit CopyData( QString::fromWCharArray((wchar_t *)pdata->lpData) );

и отправку можно проще сделать
Код: plaintext
1.
2.
3.
4.
5.
        COPYDATASTRUCT data;
        data.cbData = ui->lineEdit->text().size() * 2;
        data.dwData = 33;
        data.lpData = ui->lineEdit->text().data();
        SendMessage(hChild, WM_COPYDATA, reinterpret_cast<WPARAM>(winId()), reinterpret_cast<LPARAM>(&data));
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583637
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_Sla,

data.cbData = ui->lineEdit->text().size() * 2;

Вот это что за хрень?
Почему на два?
Это либо utf8, либо utf16, и в любом случае надо вычислять реальный размер строки в байтах. И он может быть некратен двум.
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583650
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77, спасибо за подробный ответ!

Я понял, что нужно перед отправкой добавлять нулевой символ к слову, чтоб читалась информация только до него. У меня поэтому появляются на принимающей стороне мои быквы + различные иероглифы.
Отправляющий процесс:

Код: plaintext
1.
2.
3.
4.
5.
6.
        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));



Я так понимаю, мне здесь нужно добавить '\0' символ? А к char* можно его добавлять, либо нужно по-другому писать? А когда захожу в дебаггере у меня остановка происходит после каждой введенной буквы, а на принимающей стороне только иероглифы.

А на принимающей стороне у меня так:

Код: plaintext
1.
2.
3.
4.
5.
      COPYDATASTRUCT* pdata = reinterpret_cast<COPYDATASTRUCT*>(msg->lParam);
       if (pdata->dwData == 33)
       emit CopyData(QString((char*)pdata->lpData));
       *result = 0;
       return true;
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583653
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, спасибо! Теперь понял, в это поле мы храним размер данных, которые нужно отправить.
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583674
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivm_Sla,

data.cbData = ui->lineEdit->text().size() * 2;

Вот это что за хрень?
Почему на два?
Это либо utf8, либо utf16, и в любом случае надо вычислять реальный размер строки в байтах. И он может быть некратен двум.
ui->lineEdit->text().data() возвращает указатель на QChar:
The QChar class provides a 16-bit Unicode character.

Только про '\0' забыл.
data.cbData = ui->lineEdit->text().size() * 2 + 2 ;
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583694
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mr_virtusMasterZiv, спасибо! Теперь понял, в это поле мы храним размер данных, которые нужно отправить.

Дошло наконец !
О! Я щаслиф!
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38583696
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_SlaMasterZivm_Sla,

data.cbData = ui->lineEdit->text().size() * 2;

Вот это что за хрень?
Почему на два?
Это либо utf8, либо utf16, и в любом случае надо вычислять реальный размер строки в байтах. И он может быть некратен двум.
ui->lineEdit->text().data() возвращает указатель на QChar:
The QChar class provides a 16-bit Unicode character.

Только про '\0' забыл.
data.cbData = ui->lineEdit->text().size() * 2 + 2 ;


16-bit Unicode character -- это utf-16, размер символа от 2 до 6 (если не ошибаюсь) байт.
В любом случае во всём юникоде размер символов переменный.
Постоянный только в UTF-32
...
Рейтинг: 0 / 0
отправка сообщений между процессами WM_COPYDATA
    #38584149
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ни в одной из кодировок юникода нет постоянного размера символов. Просто потому, что есть составные символы и канонические представления.
Если речь про коды (code points), то в рамках базовой плоскости и UTF-16 и UTF-32 используют фиксированное число байт на код.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / отправка сообщений между процессами WM_COPYDATA
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]