C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Обработка сообщений WinAPI, Передача AnsiString через LPARAM
tvs_spb
Отправлено: 12.08.2004, 14:11


Ученик-кочегар

Группа: Участник
Сообщений: 20



Как с помощью LParam сообщения,посылаемого одним приложением другому,передать AnsiString.С передачей интов всё просто,а вот строку никак не получается. Хотя виндовский wm_settext это делает.Примерчик бы ...
Guest
Отправлено: 12.08.2004, 14:26


Не зарегистрирован







AnsiString порждение Borland'а используйте метод c_str()
Например:
AnsiString text = "some text"
char* cp = text.c_str();
tvs_spb
Отправлено: 12.08.2004, 14:36


Ученик-кочегар

Группа: Участник
Сообщений: 20



Посылаю:

AnsiString text = "some text";
char* cp = text.c_str();
PostMessage(hd,MY_MSG,0,(LPARAM)cp);

Обрабатываю:

void __fastcall TForm1::SetMText(TMessage &Message)
{
AnsiString mes=Message.LParam;
Label1->Caption=mes;
}

В Label выводятся цифры , а не "some text"
Guest
Отправлено: 12.08.2004, 15:05


Не зарегистрирован







А так ?
Посылам:
PostMessage(hd, MY_MSG, 0, AnsiString("some text).c_str());

Ловим:
AnsiString str = AnsiString((char*)(Message.LParam));

Вы к строке преобразовывали адрес строки вместо содержимого
olegenty
Отправлено: 12.08.2004, 15:17


Ветеран

Группа: Модератор
Сообщений: 2412



LParam имеет тип long.
AnsiString великолепно преобразует его и показывает на экран.
ведь копьютер-то не в курсе, что ты впихнул в long указатель на строку, заканчивающуюся символом \0. он лишь проверил, влазит ли этот указатель в long. есс-но влазит. вот и всё.

поэтому приведение должно быть явным. ты как бы компу говоришь: "дурень, там же строка...". выглядит это так:

CODE

void __fastcall TForm1::SetMText(TMessage &Message)
{
   char *sz = reinterpret_cast<char*>(Message.LParam);
   Label1->Caption = AnsiString(sz);
}
tvs_spb
Отправлено: 12.08.2004, 15:18


Ученик-кочегар

Группа: Участник
Сообщений: 20



Во-первых,спасибо за участие.
А во-вторых,так в str NULL,по такому адресу он ничего не получает
olegenty
Отправлено: 12.08.2004, 15:19


Ветеран

Группа: Модератор
Сообщений: 2412



упс. опоздал с ответом. пардон. smile.gif
tvs_spb
Отправлено: 12.08.2004, 15:23


Ученик-кочегар

Группа: Участник
Сообщений: 20



olegenty!
К сожалению,приведённый код также приводит к NULL в sz
olegenty
Отправлено: 12.08.2004, 15:24


Ветеран

Группа: Модератор
Сообщений: 2412



рабочий пример:

User Attached Image Скачать файл
SendMsg.zip


tvs_spb
Отправлено: 12.08.2004, 15:32


Ученик-кочегар

Группа: Участник
Сообщений: 20



За пример спасибо.
Вот только в примере всё выполняется внутри адресного пространства одной программы,а у меня то посылает одна,а читает другая...может отсюда ноги растут?
olegenty
Отправлено: 12.08.2004, 15:37


Ветеран

Группа: Модератор
Сообщений: 2412



Йоп. Тогда специальной функцией, имя забыл, надо память под строку выделить, запипирить туда строку, а в обработчике считать строку да и удалить блок из памяти. Тоже специальной функцией, и её имя, увы, навскидку не вспоминается.

либо обе проги должны использовать одну DLL — она будет в адресном пространстве обеих прог. (если не по сети)
Guest
Отправлено: 12.08.2004, 15:45


Не зарегистрирован







QUOTE
Тогда специальной функцией, имя забыл, надо память под строку выделить, запипирить туда строку, а в обработчике считать строку да и удалить блок из памяти. Тоже специальной функцией, и её имя, увы, навскидку не вспоминается


Насколько помню WM_SetText делает именно это
olegenty
Отправлено: 12.08.2004, 15:45


Ветеран

Группа: Модератор
Сообщений: 2412



по-моему

::SysAllocString и ::SysFreeString соответственно. (описание см. в Win32 SDK)
olegenty
Отправлено: 12.08.2004, 15:47


Ветеран

Группа: Модератор
Сообщений: 2412



нет, WM_SETTEXT этого не делает, см. всё тот же Win32 SDK.
tvs_spb
Отправлено: 12.08.2004, 16:44


Ученик-кочегар

Группа: Участник
Сообщений: 20



Вот именно WM_SETTEXT и заронила в мою душу сомнения.
Она то без проблем устанавливает Заголовок окна с известным хендлером,причём текст передаёт именно в lparam.
Значит дело тут не в адресном пространстве,а в корректном обработчике.
Guest
Отправлено: 12.08.2004, 17:08


Не зарегистрирован







Цитирую чужой ответ оригинал здесь
QUOTE

Дейсвительно, каждый прцесс имеет собственное виртуальное адресное пространство, которое скрыто от других процессов.
Что же касается WM_SETTEXT, то процитирую товарища Рихтера:

--------------------------------------------------------------------------------

Рассмотрим такой вызов:
SendMessage(FindWindow(NULL, "Calculator"), WM_SETTEXT, 0, (LPARAM) "A Test Caption" );
Вроде бы все достаточно безобидно определяется описатель окна Calculator и делается попытка изменить его заголовок на «A Test Caption». Но приглядимся к тому, что тут происходит. В lParam передается адрес строки (с новым заголовком), расположенной в адрес ном пространстве Вашего процесса. Получив это сообщение, оконная процедура программы Calculator берет lParam и пытается манипулировать чем-то, что, «по ее мнению», является указателем на строку с новым заголовком.
Но адрес в lParam указывает на строку в адресном пространстве Вашего процесса, а не программы Calculator. Вот Вам и долгожданная неприятность — нарушение доступа к памяти. Но если Вы все же выполните показанную ранее строку, все будет работать нормально. Что за наваждение?
А дело в том, что система отслеживает сообщения WM_SETTEXT и обрабатывает их не так, как большинство других сообщений. При вызове SendMessage внутренний код функции проверяет, не пытаетесь ли Вы послать сообщение WM_SETTEXT. Если это так, функция копирует строку из Вашего адресного пространства в проекцию файла и делает его доступным другому процессу. Затем сообщение посылается пото ку другого процесса. Когда поток-приемник готов к обработке WM_SETTEXT, он оп ределяет адрес общей проекции файла (содержащей копию строки) в адресном про странстве своего процесса. Параметру lParam присваивается значение именно этого адреса, и WM_SETTEXT направляется нужной оконной процедуре. После обработки этого сообщения, проекция файла уничтожается
olegenty
Отправлено: 13.08.2004, 07:22


Ветеран

Группа: Модератор
Сообщений: 2412



поэкспериментировал. SysAllocString не спасает.
Так что единственное, что тут может быстро помочь, это DLL, которая по определению будет в адресном пространстве обеих программ. (как бы их пересечением)

Вернуться в Вопросы программирования в C++Builder