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
|
упс. опоздал с ответом. пардон.
|
|
tvs_spb |
Отправлено: 12.08.2004, 15:23 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 20
|
olegenty!
К сожалению,приведённый код также приводит к NULL в sz |
|
olegenty |
Отправлено: 12.08.2004, 15:24 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
рабочий пример:
|
|
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, которая по определению будет в адресном пространстве обеих программ. (как бы их пересечением)
|
|