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

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

01.10.2011, 10:22. Показов 31868. Ответов 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
8488 / 6155 / 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
Ответ Создать тему
Новые блоги и статьи
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
1С: Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
1С: Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
Krabik - рыболовный бот для WoW 3.3.5a
AmbA 21.03.2026
без регистрации и смс. Это не торговля, приложение не содержит рекламы. Выполняет свою непосредственную задачу - автоматизацию рыбалки в WoW - и ничего более. Однако если админы будут против -. . .
1С: Программный отбор элементов справочника по значению перечисления
Maks 21.03.2026
Установка программного отбора элементов справочника "Сотрудники" из модуля формы документа. В качестве фильтра для отбора служит значение перечислений. / / Событие "НачалоВыбора" реквизита на форме. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru