Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.81/160: Рейтинг темы: голосов - 160, средняя оценка - 4.81
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744

SendMessage (Передать строку другому приложению)

01.10.2011, 10:22. Показов 31714. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Возникла проблема при передаче строки из одного приложения в другое.
(XE)

Передача(1-й вариант (рабочий))
C++
1
2
char* str = "C:\\example.mp3";      
SendMessage(h, WM_GETSTRING ,(WPARAM)str, NULL);
Передача(2-й вариант (цель)) // Призывает Access Violation)) с StrCopy тоже самое!
C++
1
2
3
AnsiString S = "C:\\example.mp3";
char* str = S.c_str();
SendMessage(h, WM_GETSTRING ,(WPARAM)str, NULL);
Прием:
C++
1
2
3
4
5
void __fastcall TMainForm::OnGetString(TMessage& Msg)
{
    char* Str = (char*)Msg.WParam;
    Label1->Caption = String(Str);
}
То есть: Требуется передать переменную S!
Заранее благодарю за любые советы!
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.10.2011, 10:22
Ответы с готовыми решениями:

Передать текст другому приложению
Есть программа, в ней есть текстовый компонент Мемо, задача стоит такая: 1. Нужно передать текст из этого компонента в другую...

Передача массива байтов по UDP протоколу другому приложению
Как в BorlandС++ Builder6 решается вопрос обмена информацией с другими приложениями (не обязательно созданными в С++ Builder)? Например,...

Как отослать текстовое сообщение другому приложению. .SendMessage. WM_COPYDATA. Delphi
Всем привет. Есть такая программа, отправляющая текстовое сообщение другой программе через sendmessage. Программа отправитель: ...

25
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
01.10.2011, 12:33
Надёжней всего со строками использовать сообщение WM_COPYDATA

C++
1
2
3
4
5
6
COPYDATASTRUCT cd;
AnsiString sBuffer = "Test string";
cd.lpData=&sBuffer;
cd.cbData= sBuffer.Length();
 
SendMessage(hwnd,WM_COPYDATA, 0, (LPARAM) &cd);
Принимаем:

C++
1
2
3
void TForm1::WMCopyData(TWMCopyData &Msg) {
       const AnsiString sText = Msg.CopyDataStruct.lpData;
}
П.С. Не забыть описать в карте сообщений в заголовке класса прототип принимающей функции.

Кстати, таким же образом можно передавать не только строки, но даже структуры данных.
3
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
01.10.2011, 13:15  [ТС]
Maluda Спасибо, не знал, что можно обойтись без создания своего типа сообщения, но не удается реализовать его на XE...

Сначала XE ругался на это:
C++
1
const AnsiString sText = Msg.CopyDataStruct.lpData;
Заменил:
C++
1
const AnsiString sText = (char*)Msg.CopyDataStruct->lpData;
Теперь отображает 2-3 (вроде как китайских) иероглифа
Пробовал все это дело в Unicode, но лучший результат это первая буква каталога с двоеточием ("С:" + иероглифы)
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
02.10.2011, 00:35
Лучший ответ Сообщение было отмечено как решение

Решение

Да, там действительно странности какие-то были с AnsiString. Сейчас сбрасываю рабочий вариант.
Проверил и протестировал.
Чтобы время не терять и приём, и передачу поместил в одно приложение.
Скомпилируешь приложение, а для второго экземпляра закомментируешь наоборот заглавие формы.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
 
//---------------------------------------------------------------------------
class TForm1 : public TForm {
__published: // IDE-managed Components
    TButton *btn1;
    void __fastcall btn1Click(TObject *Sender);
 
private: // User declarations
 
public: // User declarations
    __fastcall TForm1(TComponent* Owner);
 
    void __fastcall OnWMCopyData(TWMCopyData &Msg);
 
    BEGIN_MESSAGE_MAP
 
        MESSAGE_HANDLER(WM_COPYDATA, TWMCopyData, OnWMCopyData);
 
    END_MESSAGE_MAP(TForm);
};
 
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
    this->Caption = "Receiver";
    // this->Caption = "Sender"; // РАССКОММЕНТИРОВАТЬ ДЛЯ ВТОРОГО ЭКЗЕМПЛЯРА.
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::OnWMCopyData(TWMCopyData &Msg) {
    const AnsiString sTest = (char*)Msg.CopyDataStruct->lpData;
    ShowMessage(sTest);
}
 
void __fastcall TForm1::btn1Click(TObject *Sender) {
    COPYDATASTRUCT cd;
    const AnsiString sTest = "Testing string";
    cd.cbData = sTest.Length() + 1;
    cd.lpData = sTest.c_str();
    SendMessageA(FindWindowA(NULL, "Receiver"), WM_COPYDATA, 0, (LPARAM)&cd);
}
//---------------------------------------------------------------------------
9
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
02.10.2011, 00:38
Должно получиться вот так
Миниатюры
SendMessage (Передать строку другому приложению)  
2
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
02.10.2011, 11:47  [ТС]
Maluda Спасибо большое! Все прекрасно работает. В этом "+1" прям загадка какая-то
Кстати у меня тоже все это происходит в одном приложении.

Раз уж такая тема спрошу, верно ли я все делаю?

1)Плеер открыт ждет сообщения WM_COPYDATA
2)DblClick на песне в папке - Открывается второй экземпляр и в конструкторе мьютексом проверяет запущен ли уже "..Player"
3)Если да, переименовывает себя, ищет дексриптор окна с именем "..Player" и отправляет ему WM_COPYDATA ВАШИМ(Maluda) способом..
4)1-ый экземпляр принимает строку и запускает трек.

Но проблема в том, что происходит это все примерно 3 секунды.
По сравнению с современными плеерами, которые открывают меньше чем за 0.5 сек, это безобразие

Можно как то ускорить этот процесс?
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
02.10.2011, 12:30
Я уверен, что проблема не в отправке сообщения или обработке её приёма,
а в открытии-запуске файла, поэтому вопрос: какими средствами файл открываешь, какую библиотеку используешь?
0
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
02.10.2011, 12:49  [ТС]
Bass.dll, но DblClick в плейлисте открывает файл мгновенно, точно так же открываю после получения сообщения..
Только что поставил ShowMessage Первой строкой конструктора формы, и вышло это сообщение именно через 3 сек после дабл-клика на песне в папке
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
02.10.2011, 13:03
Не совсем понятно, что у тебя за структура приложения. Надо код смотреть.
0
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
02.10.2011, 14:53  [ТС]
VCL Forms Application.. Конструктор формы я так понимаю выполняется в первую очередь сразу после запуска. Остается только думать что ассоциация муз.файлов с моей программой настроена некорректно.
Вот так я настроил ассоциацию:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void __fastcall TMainForm::btnRegClick(TObject *Sender)
{
    TRegistry *Reg;
    AnsiString fname;
    Reg = new TRegistry;
    try {
        Reg->RootKey = HKEY_CLASSES_ROOT;
        Reg->OpenKey("\\.mp3",true);
        Reg->WriteString("","XboolPlayer");
        Reg->CloseKey();
 
        Reg->RootKey = HKEY_CLASSES_ROOT;
        Reg->OpenKey("\\.m3u",true);
        Reg->WriteString("","XboolPlayer");
        Reg->CloseKey();
 
        Reg->RootKey = HKEY_CLASSES_ROOT;
        Reg->OpenKey("\\.plc",true);
        Reg->WriteString("","XboolPlayer");
        Reg->CloseKey();
 
        Reg->OpenKey("\\XboolPlayer",true);
        Reg->WriteString("","My document");
        Reg->CloseKey();
 
        Reg->OpenKey("\\XboolPlayer\\Shell\\Open\\Command",true);
        Reg->WriteString("",ParamStr(0)+"\"%1\"");
        Reg->CloseKey();
 
        Reg->OpenKey("\\XboolPlayer\\DefaultIcon",true);
        Reg->WriteString("",ParamStr(0)+", 1");
        Reg->CloseKey();
 
        Reg->OpenKey("\\.mp3\\DefaultIcon",true);
        Reg->WriteString("",ParamStr(0)+", 1");
        Reg->CloseKey();
    }
    __finally {
        if (Reg != NULL) {
            delete Reg;
        }
    }
}
0
 Аватар для Maluda
1280 / 598 / 116
Регистрация: 18.08.2009
Сообщений: 832
02.10.2011, 21:45
В том то и дело, что конструктор формы выполняется только после того, как на форме построены все компоненты.
А так как компоненты - это тоже классы, то соответственно, конструктор формы выполнится только после выполнения конструкторов всех компонентов.
И если на форме у тебя 50 компонентов или картинки большого разрешения, или просто много картинок, то на всё это потратится время.
Чтобы сократить время загрузки формы, необходимо как можно меньше сделать *.dfm файл формы. Чем он больше в размере будет, тем дольше будет загрузка формы.
1
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
02.10.2011, 22:05  [ТС]
А можно как то вставить мьютекс и отправить сообщение 1-му экземпляру, до создания всех компонент? А то и правда у меня чего на форме только нет..

Интуиция подсказывает что сделать это нужно в WinMain...
C++
1
2
3
4
5
6
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        Application->Initialize();
       . . .
Видно, что это выполняется в первую очередь.. но никак не получается вставить сюда хоть какой то код, приложение вообще не запускается.
Мб есть способ?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
03.10.2011, 01:36
может, стоит это делать до Application->Initialize();
0
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
03.10.2011, 10:13  [ТС]
Цитата Сообщение от LK Посмотреть сообщение
может, стоит это делать до Application->Initialize();
LK Я пробовал! Но приложение вообще не запускается и ничего не происходит если вставить это:
C++
1
2
3
4
5
6
HANDLE hMutex=CreateMutexA(NULL,TRUE,"XboolPlayer");
if (!GetLastError()==ERROR_ALREADY_EXISTS)
{
    CloseHandle(hMutex);
    ShowMessage("You can do it!");
}
А вот просто ShowMessage работает!

Добавлено через 26 минут
Почему эта строка убивает приложение?
C++
1
    HANDLE hMutex=CreateMutexA(NULL,TRUE,"XboolPlayer");
0
Now I Matrix
137 / 134 / 28
Регистрация: 01.03.2010
Сообщений: 223
03.10.2011, 10:37
C++
1
2
3
4
5
6
7
HANDLE hMutex=CreateMutexA(NULL,TRUE,"XboolPlayer");
if (GetLastError()==ERROR_ALREADY_EXISTS)
{
        CloseHandle(hMutex);
        ShowMessage("You can do it!");
        exit(1);
}
Найди 2 отличия

( на XP работает )
0
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
03.10.2011, 11:47  [ТС]
Сразу после компиляции вылетает! Не забудьте про контекст!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        HANDLE hMutex=CreateMutexA(NULL,TRUE,"XboolPlayer");
            // до этой строки не доходит))     
            if (GetLastError()==ERROR_ALREADY_EXISTS)
        {
            CloseHandle(hMutex);
            ShowMessage("You can do it!");
            exit(1);        
        }                           
        Application->Initialize();
       . . .
Добавлено через 27 минут
А зачем нужен Mutex, если можно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    HWND h = FindWindowA(NULL, "XboolPlayer");
    if (h) {
        COPYDATASTRUCT cd;
        const AnsiString sBuffer = ParamStr(1);
        cd.cbData = sBuffer.Length() + 1;
        cd.lpData = sBuffer.c_str();
        SendMessage(h, WM_COPYDATA,0, (LPARAM) &cd);
        Application->Terminate();
    }
    else
    try
    {
        Application->Initialize();
 
. . .
0
Прогер
 Аватар для Programmer.
632 / 263 / 15
Регистрация: 17.11.2010
Сообщений: 1,371
Записей в блоге: 2
04.10.2011, 05:48
__bool,
Попробуй, Наверно ты окну отправляеш слишком много месиджов для оброботки, и оно не успевает за 0.5 сек отреагировать на них ...
Покажи код если можно, и не забуд очишать прграмму за собой...
C++
1
Application->ProcessMessages();
ААх не заметил 2 ую страницу...

Я вообше не понимаю, если ты нашел ришение, зачем вообше мутекс?
0
 Аватар для __bool
288 / 229 / 27
Регистрация: 13.06.2010
Сообщений: 744
04.10.2011, 07:29  [ТС]
Цитата Сообщение от Programmer. Посмотреть сообщение
Я вообше не понимаю, если ты нашел ришение, зачем вообше мутекс?
И правда, я теперь тоже не понимаю зачем он)
мьютекс проверяет по имени, так и FindWindow тоже.
А чтоб не найти самого себя, мы можем переименовать себя, и произвести поиск

Добавлено через 9 минут
Даже если до Initialize() вставить проверку, отправить сообщение 1-му экземпляру и закрыть себя, 1-ый экземпляр получает сообщение через 3 секунды(примерно) Словно после DoubleClick в папке, Windows что-то там свое делает, а потом запускает.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.02.2012, 15:22
Я использовал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#define WM_MyDeskTopShow WM_USER+5
//---------------------------------------------------------------------------
USEFORM("UStyleWindow.cpp", FStyleWindow);
USEFORM("UMyDeskTop.cpp", FMyDeskTop);
//---------------------------------------------------------------------------
const char *mutexname = "mutexMyDeskTop091211";
//---------------------------------------------------------------------------
WINAPI _tWinMain(HINSTANCE,HINSTANCE,LPTSTR,int)
{
//------------------ Запущина ли копия программы ?----------------
        HWND  hMutex  = CreateMutex(NULL, true, mutexname);
        DWORD LastErr = GetLastError();
 
        if ((LastErr == ERROR_ALREADY_EXISTS)||
            (LastErr == ERROR_INVALID_HANDLE)||
            (!hMutex))
           {
            HWND hDesk = FindWindow("TFMyDeskTop",NULL);
 
            if(ParamCount()==1)
              {
              COPYDATASTRUCT cd;
              String text = ParamStr(1);
              cd.lpData = text.c_str();
              // Передача имени файла
              SendMessage(hDesk, WM_COPYDATA, 0, (LPARAM)&cd);
              }
            else
                {
                // Сообщение о том что надо паказать окно
                SendMessage(hDesk,WM_MyDeskTopShow,0,0);
                }
            exit(1);
           }
//-----------------------------------------------------------
    try
    {
        Application->Initialize();
        Application->MainFormOnTaskBar = true;
        Application->Title = "MyDeskTop";
        Application->CreateForm(__classid(TFMyDeskTop), &FMyDeskTop);
        Application->CreateForm(__classid(TFStyleWindow), &FStyleWindow);
        Application->Run();
    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//--------------------------------------------------------------------------
void __fastcall TFMyDeskTop::OnWMCopyData(TWMCopyData &Msg)
{
Visible= true;
SetForegroundWindow(Handle);
 
sFileDesk= (char*)Msg.CopyDataStruct->lpData;// изменение пути к текущему файлу
 
AcLoadFile->Execute();// Загрузка файла
AcUpdateListBox->Execute();
ImRepaint();
}
//----------------------------------------------------------------------------
Проблема в том что новый файл открыватся(т.е передается сообщение с путем к нему) лишь иногда.
0
05.09.2013, 01:08

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Проблема в том что новый файл открыватся(т.е передается сообщение с путем к нему) лишь иногда.
Эту проблему решил заменой мютекса на событие, кому интересно смотрите исходники из блога https://www.cyberforum.ru/blog... og621.html

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.09.2013, 01:08
Помогаю со студенческими работами здесь

Передать нажатие клавиши другому приложению
предположим, что по нажатию F5 в программе выполняются определенные действия. как передать из моей программы в эту нажатие F5?

Передача команд другому приложению.
Всем доброго времени суток. Я так сказать новичок в Делфи, и у меня есть вопрос. Как сделать следующее: 1)Есть моя программа. ...

Передача данных другому приложению
Появилась потребность передавать данные между двумя отдельными приложениями. Как можно такое реализовать. Т.е. надо, чтобы из одного...

Передача строки другому приложению
Итак дано: Два приложения могут общаться между собой посредством системных сообщений. То есть есть возможность от одного приложения...

Отправка события другому приложению
Суть такова. Есть приложение Б. Оно существует как отдельное, созданное не мной. Нужно подменить отправляемые операционной системой ему...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru