Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/30: Рейтинг темы: голосов - 30, средняя оценка - 4.77
2 / 2 / 0
Регистрация: 11.09.2013
Сообщений: 129
1

Как передать сообщение из одной программы в другую?

22.03.2014, 15:01. Показов 5996. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Например , у меня есть такой кусок кода:
C++
1
2
3
4
5
6
7
8
BOOL CALLBACK fnEnumWindowProc(HWND hwnd,LPARAM lParam){
  fprintf(stdout,"%8.8x\n", (long)hwnd);
  return TRUE;
}
int main(){ 
  EnumWindows(fnEnumWindowProc, 0);
  return 0;
}
В нём выводятся хендлы всех окон ( в виде чисел)
Мне нужно эти значения этих хендлов передать в другую программу ( в виде чисел , чтобы выводились в окне ) .
Не могу понять, как это сделать . Нужно создавать 2 программы ? Или какую функцию для этого нужно использовать ?
Помогите , пожалуйста .
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.03.2014, 15:01
Ответы с готовыми решениями:

Как передать данные с одной программы в другую?
Такой вопрос: запущены 2 проги на разных компьютерах, одна получает данные и анализирует и как...

Как передать информацию из одной программы в другую
Одна программа на С#, вторая на Delphi. Из первой во вторую нужно послать строку, после чего вторая...

Передать переменную из одной программы в другую
Здравствуйте! Как сделать чтобы одна программа передавала переменную, а другая принимала её?...

Передать значение переменной из одной программы в другую
Всем добрый вечер. Появилась такая задача:передать значение переменной из одной программы в...

8
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
22.03.2014, 20:29 2
Обмен данными между процессами:

Разделяемая память (или отображаемые в память файлы);
Каналы (pipes);
Мэйлслоты (mailslots);
Файлы;
Реестр;
Оконные сообщения;
Сокеты;
COM/RPC;
...

Interprocess Communications (MSDN)
http://msdn.microsoft.com/en-u... 85%29.aspx
1
2 / 2 / 0
Регистрация: 11.09.2013
Сообщений: 129
22.03.2014, 21:02  [ТС] 3
Мне скорее всего нужно через оконное сообщение ,через функцию SendMessage
В общем ,я создал одну программу , в которой создаётся ListBox с заголовками всех окон в системе :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <windows.h>
#include <windowsx.h>
#include <vector>
 
 
LRESULT CALLBACK HelloWorldWndProc(HWND,UINT,UINT,LONG);
BOOL CALLBACK MyEnum(HWND hWnd,LPARAM lParam);
HWND ListBox1;
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{ 
    WNDCLASS WndClass;
    WndClass.style=0;
    WndClass.lpfnWndProc=HelloWorldWndProc;
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hInstance=hInstance;
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName=NULL;
    WndClass.lpszClassName=L"MyWindow";
 
    if(!RegisterClass(&WndClass))
    {
        MessageBox(NULL,L"Невозможно зарегестрировать класс окна!",L"Ошибка",MB_OK);
        return 0;
    }
 
    HWND hWnd;
    hWnd=CreateWindow(L"MyWindow",L"MyWindow",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
        CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    if(!hWnd)
    {
        MessageBox(NULL,L"Невозможно создать окно!",L"Ошибка",MB_OK);
        return 0;
    }
 
    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);
 
    MSG Msg;
    while(GetMessage(&Msg,NULL,0,0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
 
    return Msg.wParam;
}
 
BOOL CALLBACK MyEnum(HWND hWnd,LPARAM lParam)
{
    TCHAR  WindowText [255]; TCHAR str [255] ;
    GetWindowText(hWnd, (LPWSTR)WindowText, 255);
    GetClassName(hWnd,(LPWSTR)str,255);
    SendMessage(ListBox1,LB_ADDSTRING,0,(LPARAM)str);
    SendMessage(ListBox1,LB_ADDSTRING,0,(LPARAM)WindowText);
    return true;
 }
 
LRESULT CALLBACK HelloWorldWndProc(HWND hWnd,UINT Message,UINT wParam,LONG lParam)
{
    switch(Message)
    {
    case WM_DESTROY:
        {
        PostQuitMessage(0);
        }break;
    case WM_LBUTTONDOWN:
        EnumWindows(MyEnum, 0);
       break;
      case WM_CREATE:
        {
 
ListBox1=CreateWindowEx(0,L"listbox",0,WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|WS_HSCROLL,50,50,300,300,hWnd,0,0,0);
        }break;
        return 0;
    }
    return DefWindowProc(hWnd,Message,wParam,lParam);
}
Мне нужно как-то передать эти заголовки ещё в одну программу . Вот как это реализовать , что нужно сделать ? Догадываюсь , что нужно как-то использовать функцию SendMessage ..
конкретного плана нету ; это нужно создавать отдельно проект ещё один или как?
помогите , пожалуйста , я уже в тупике просто
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
22.03.2014, 21:55 4
Цитата Сообщение от VASYA_A Посмотреть сообщение
Мне нужно как-то передать эти заголовки ещё в одну программу . Вот как это реализовать , что нужно сделать ? Догадываюсь , что нужно как-то использовать функцию SendMessage .
Можно и SendMessage, хотя для обмена данными между процессами
это далеко не лучший вариант. Там есть специальное сообщение -
WM_COPYDATA, подробности на MSDN:

WM_COPYDATA message (Windows)
http://msdn.microsoft.com/en-u... 85%29.aspx

Одно приложение записывает данные в буфер, упаковывает все
это в структуру COPYDATASTRUCT, находит окно второго приложения и
шлет ему SendMessage с этим сообщением. Второе приложение
обрабатывает сообщение и возвращает TRUE.

Но я бы сделал по-другому, хотя бы и через разделяемую память.
Это и надежнее, и быстрее, и концептуальнее (ну не предназначены
оконные сообщения для межпроцессного обмена).
0
2 / 2 / 0
Регистрация: 11.09.2013
Сообщений: 129
23.03.2014, 13:33  [ТС] 5
мне нужно именно через SendMessage
да, я читал про WM_COPYDATA , но немного запутался с обработкой этого сообщения
вот код программы- отправителя :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <windows.h>
#include <windowsx.h>
#include <vector>  
 
COPYDATASTRUCT p;  //экземпляр структуры
 
 
 
 
LRESULT CALLBACK HelloWorldWndProc(HWND,UINT,UINT,LONG);
BOOL CALLBACK MyEnum(HWND hWnd,LPARAM lParam);
HWND ListBox1;
HWND hw;
 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{ 
    WNDCLASS WndClass;
    WndClass.style=0;
    WndClass.lpfnWndProc=HelloWorldWndProc;
    WndClass.cbClsExtra=0;
    WndClass.cbWndExtra=0;
    WndClass.hInstance=hInstance;
    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.lpszMenuName=NULL;
    WndClass.lpszClassName=L"MyWindow";
 
    if(!RegisterClass(&WndClass))
    {
        MessageBox(NULL,L"Невозможно зарегестрировать класс окна!",L"Ошибка",MB_OK);
        return 0;
    }
 
    HWND hWnd;
    hWnd=CreateWindow(L"MyWindow",L"MyWindow",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
        CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
    if(!hWnd)
    {
        MessageBox(NULL,L"Невозможно создать окно!",L"Ошибка",MB_OK);
        return 0;
    }
 
    ShowWindow(hWnd,nCmdShow);
    UpdateWindow(hWnd);
 
    MSG Msg;
    while(GetMessage(&Msg,NULL,0,0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
 //заполнение структуры
p.dwData=123;
p.cbData=sizeof(ListBox1);
p.IpData=&ListBox1;
//отправка сообщения
 
hw=FindWindow(TEXT("Класс получателя"),TEXT("Получатель"));
SendMessage(hw,WM_COPYDATA,0,(LPARAM)&p);
 
 
    return Msg.wParam;
}
 
BOOL CALLBACK MyEnum(HWND hWnd,LPARAM lParam)
{
    TCHAR  WindowText [255]; TCHAR str [255] ;
    GetWindowText(hWnd, (LPWSTR)WindowText, 255);
    GetClassName(hWnd,(LPWSTR)str,255);
    SendMessage(ListBox1,LB_ADDSTRING,0,(LPARAM)str);
    SendMessage(ListBox1,LB_ADDSTRING,0,(LPARAM)WindowText);
    return true;
 }
 
LRESULT CALLBACK HelloWorldWndProc(HWND hWnd,UINT Message,UINT wParam,LONG lParam)
{
    switch(Message)
    {
    case WM_DESTROY:
        {
        PostQuitMessage(0);
        }break;
    case WM_LBUTTONDOWN:
        EnumWindows(MyEnum, 0);
       break;
      case WM_CREATE:
        {
 
ListBox1=CreateWindowEx(0,L"listbox",0,WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|WS_HSCROLL,50,50,200,500,hWnd,0,0,0);
        }break;
        return 0;
    }
    return DefWindowProc(hWnd,Message,wParam,lParam);
}
вот код программы- получителя:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <windows.h> 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HWND ListBox1; //дескриптор списка
// Главная функция:
int WINAPI WinMain(HINSTANCE hInst, 
                   HINSTANCE hPrevInst, 
                   LPSTR lpCmdLine,
                   int nCmdShow) 
{
    
    HWND hMainWnd; // создаём дескриптор будущего окошка
    MSG msg;
    WNDCLASSEX wc; // создаём экземпляр, для обращения к членам класса WNDCLASSEX
    wc.cbSize        = sizeof(wc); 
    wc.style         = CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS; 
    wc.lpfnWndProc   = WndProc;
    wc.lpszMenuName  =  0; 
    wc.lpszClassName = L"Класс получателя"; 
    wc.cbWndExtra    = NULL; 
    wc.cbClsExtra    = NULL; 
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); 
    wc.hIconSm       = LoadIcon(NULL, IDI_WINLOGO); 
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
    wc.hInstance     = hInst; 
    if(!RegisterClassEx(&wc)){
       
        MessageBox(NULL, L"Не получилось зарегистрировать класс!", L"Ошибка", MB_OK);
        return NULL; 
    }
    // Функция, создающая окошко:
    hMainWnd = CreateWindow(L"Класс получателя",L"Получатель",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
        CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL);
    if(!hMainWnd){
   
        MessageBox(NULL, L"Не получилось создать окно!", L"Ошибка", MB_OK);
        return NULL;
    }
    ShowWindow(hMainWnd, nCmdShow);
    UpdateWindow(hMainWnd);
 
    while(GetMessage(&msg, NULL, NULL, NULL)){ 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam; 
}
 //обратотка сообщений
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 
   COPYDATASTRUCT *pc;
   switch(uMsg){
    case WM_DESTROY: 
        PostQuitMessage(NULL); 
        break;
        //создание списка в получателе
         case WM_CREATE:
        {    ListBox1=CreateWindowEx(0,L"listbox",0,WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|WS_HSCROLL,50,50,300,300,hWnd,0,0,0);
        }
        break;
        //получение данных
         case WM_COPYDATA:
         pc=(COPYDATASTRUCT*)IParam;
         
         /*дальше не знаю, что писать*/
       
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam); 
    }
return NULL; 
}
в программе- получителе я запутался , как обрабатывать сообщение
C++
1
2
3
4
 case WM_COPYDATA:
         pc=(COPYDATASTRUCT*)IParam;
         
         /*дальше не знаю, что писать*/
как заполнить список?

Помогите, пожалуйста , я не знаю, что дальше нужно делать уже . Заранее спасибо!

Добавлено через 1 час 33 минуты
Я уже немного изменил текст
наверное , здесь нужно, чтобы первая программа ничего не выводила , а только находила заголовки ( убрал WM_CREATE)

проблема со вторым приложением : ругается на IParam ( это же получается указатель на место , куда я должен впихнуть список?)
ругается скорее всего из-за того , что не выделил память на список
думаю , нужно чтобы было так: 1-е приложение ничего не выводит на экран,
только заполняет перечень заголовков окон в памяти и передаёт его посредством WM_COPYDATA во второе приложение. 2-е приложение получивши сообщение WM_COPYDATA выделяет из него строки и выводит в листбокс

как выделить память ??
Очень прошу Вашей помощи ! Голова кипит уже((
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
23.03.2014, 13:43 6
Цитата Сообщение от VASYA_A Посмотреть сообщение
C++
1
2
3
4
//заполнение структур
p.dwData=123;
p.cbData=sizeof(ListBox1);
p.IpData=&ListBox1;
Здесь попытка передать в другой процесс хэндл лист-бокса.
Смысла в этом нет никакого. Нужно передавать не хэндл, а
сами данные, которые находятся в лист-боксе.
Например, сформировать массив строк, разделенных нулями, с
двойным нулем на конце (null-terminated string array) и записать
указатель на его начало в lpData, а размер (в байтах) - в cbData.

Добавлено через 1 минуту
Цитата Сообщение от VASYA_A Посмотреть сообщение
ругается на IParam
Должно быть не IParam, а lParam. Смотрите объявление аргументов
функции WndProc.

Добавлено через 1 минуту
И отправку сообщения WM_COPYDATA лучше делать из оконной
процедуры, а не на выходе из нее, когда никакого дочернего
лист-бокса уже быть не может.
1
2 / 2 / 0
Регистрация: 11.09.2013
Сообщений: 129
23.03.2014, 16:03  [ТС] 7
спасибо
вот так нужно делать?
C++
1
2
3
4
5
TCHAR** arr = newTCHAR*[255];
 
p.dwData=123;
p.cbData=sizeof(arr);
p.IpData=&arr;
Добавлено через 9 минут
Помогите, пожалуйста , хоть немного, дописать это всё
запутался совсем -что и куда(

Добавлено через 1 час 58 минут
не поможете?
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
23.03.2014, 16:52 8
Цитата Сообщение от VASYA_A Посмотреть сообщение
не поможете?
Дык уже помогаю. Или помощь тогда в чем должна заключаться ?

Программа А должна передать в программу Б какие-то данные посредством
оконного сообщения WM_COPYDATA. Ок, сначала эти данные нужно
сериализовать, то есть, преобразовать в "плоский" формат, который
можно сохранять на диске или отдавать в другой процесс.

К примеру, нельзя просто передать указатель на строку в другой процесс,
т.к. там этот указатель будет указывать на что-то другое (или, что
вероятнее всего, в "пустоту"). Нужно передавать саму строку. И т.д.

Если требуется передать несколько строк, можно соединить их в один
буфер, разделив нулями.

Дальше это все "запаковывается" в структуру COPYDATASTRUCT и
вызывается SendMessage.
0
2 / 2 / 0
Регистрация: 11.09.2013
Сообщений: 129
23.03.2014, 18:00  [ТС] 9
Спасибо за разъяснения. Но у меня возникают проблемы при создании этого самого массива, чтобы указать его для p.IpData . Не пойму , как его создать и как впихнуть в него инфу с listbox-а
Скорее всего опыта не хватает
0
23.03.2014, 18:00
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.03.2014, 18:00
Помогаю со студенческими работами здесь

из одной программы в другую передать некоторые данные
Всем привет! :) нужно написать программу, чтобы она передавала какие-либо данные другой программе!...

Из одной программы передать значение переменной в другую программу (WM_COPYDATA)
Господа пытаюсь из одной программы передать значение переменной в другую , но , что то в...

Как передать Dictionary с одной формы на другую?
Доброго времени суток товарищи! Что-то никак не разберусь как можно передать Dictionary с одной...

Как передать массив из одной функции в другую?
Нужна помощь. #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int vod(int a) {...

Как из одной формы передать данные в другую
Доброго времени суток, уважаемые форумчане. Не могли б вы на пальцах объяснить как из одной формы...

Как передать данные из одной формы в другую?
нужна помощь! привожу кусок кода! ... uses ...Unit_Error; // использую его!! {$R *.dfm} ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru