powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как передать сообщение (SendMessage) C-шному приложению (консоль).
25 сообщений из 27, страница 1 из 2
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383304
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть
1) Приложение VB, ассоциируемое с Form1.hwnd
2) Приложение C++, ассоциируемое с его консолью.

С давних времен пулялся между ними файлами.
Делаю очередную попытку от этого избавиться.
Библиотеки через API к VB подключать умею, но в данном случае такой вариант не рассматривается: я не готов и НЕ буду фундаментально переписывать C-шный exe-шник.
Ставки сделаны на SendMessage (WM_COPYDATA) - метод проверен мной при эксплуатации обмена между VB-приложениями.

1. C-шное приложение посылает строку VB-шному(Form1.hwnd)
Здесь все работает, грубо так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  HWND hwndTarget = FindWindow(NULL,"My VB6 Form");
  if (hwndTarget!=0){
    std::string buffer = "My string - Hello VB6";
    COPYDATASTRUCT cds;
    cds.dwData=1;
    cds.cbData = static_cast<DWORD>(buffer.length()) + 1;
    cds.lpData = const_cast<char *>((buffer.c_str()));
    SendMessage(hwndTarget, WM_COPYDATA, 0, (LPARAM) &cds);
  }


VB-шное соответственно ловит его через сабклассинг Form1, извлекает
1) cds.dwData (номер команды)
2) cds.lpData (параметр команды, тупо строка чтоб не мучиться кот. можно парсить при необходимости)
и запускает команду на исполнение по принципу "как только так сразу".

2. А вот с обратной задачей не понимаю как сделать.
Послать и принять cds на стороне C++ через SendMessage

Код: plaintext
1.
SendMessage (hwndС-шноеПриложение, WM_COPYDATA, 0, cds)


-эту конструкцию я делать в VB умею.
Но здесь мне неясно два момента:
1) Что есть hwndС-шноеПриложение? Приложение то "консольное".
2) Что и как я должен сабклассить на стороне C++?

C-шное приложение на тек. момент имеет следующую структуру (надеюсь в приведенном фрагменте я отразил суть, в частности как оно получает данные из файла):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
PCREATE_PROCESS(CProga);
...
void CProga::Main()
...
  for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }

  }



Т.е. я хочу вместо файла слать WM_COPYDATA.
Ну и чтоб выполнялся принцип "как только так сразу", без дискретности "аля-таймер в 0,5 сек".
Как бы такой механизм в C++ подсадить?

Только, пожалуйста, не давайте мне советов выходящих за рамки вопроса как он поставлен.
Речь идет о SendMessage - куда его слать(в сторону C-приложения) и как его ловить (в C-приложении).

Т.е. я не спрашиваю о том как еще можно обмениваться данными.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383309
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Речь идет о SendMessage - куда его слать(в сторону C-приложения) и как его
ловить (в C-приложении).
Т.е. я не спрашиваю о том как еще можно обмениваться данными.
Ну так заведи в С-приложении окно и крути цикл выборки сообщений. И посылай сообщения
этому окну пока не заржавеешь.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383310
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

GetConsoleWindow()
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383312
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНу так заведи в С-приложении окно и крути цикл выборки сообщений. И посылай сообщения
этому окну

Ну, примерно такие общие слова в google я уже вычитал.

Пример кода создания окна с процедурой WindowProc дашь?
Применительно к описываемой структуре C-приложения.
Я так понимаю CreateWindow в данном случае надо вызывать из void CProga::Main() где нибудь в самом начале.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383323
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383329
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman,

>GetConsoleWindow()
Об этом ли речь и то ли это что нужно?
Понятно что, зная например заголовок окна консоли я могу найти hwnd этой консоли хотя б через FindWindow.
Но как при этом ПРИЛОЖЕНИЕ работающее в этой консоли будет получать сообщения, и выполнять в ответ на них действия - куда-то это не туда приехали.

Совет.
>Ну так заведи в С-приложении окно и крути цикл выборки сообщений.
куда более дельный.
Ну т.е. чтоб ловить оконные сообщения, надо окно.
Любое (visible=false и т.д.). Его просабклассить и использовать
в качестве сачка для ловли - не более.
В настоящий момент окна этого НЕТУ.

Осталось его создать. Идея ясна. Опыт есть, но на на C. Кода бы примерчик и лучше не голого.
Надо еще чтоб те процедуры что я вызываю из Main() виделись бы из кода сабклассинга (а как этот сабклассинг на C сделать?) этого окна (предвижу потенциальные проблемы).
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383340
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Об этом ли речь и то ли это что нужно?Это не то, что Вам нужно (сорри). Да, можно получить хэндл окна консоли,
но при этом нельзя получить доступ к оконной процедуре. В этом вся и проблема.
Дмитрий77Осталось его создать. 14780478
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383348
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanДмитрий77Осталось его создать. 14780478
Ну что ж, в этой статье чего-то есть умное на искомую тему.
На черном фоне черными буквами не сразу разглядел.
Ладно, пошел пытаться.
О результатах доложу позже.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383351
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Пример кода создания окна с процедурой WindowProc дашь?
Не дам. Сам возьми с полки пирожок, лентяй:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff381397(v=vs.85).aspx
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383390
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovНе дам. Сам возьми с полки пирожок, лентяй:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff381397(v=vs.85).aspx Dimitry, ну ты меня за школьника то не принимай (это я про лентяя). Про CreateWindowEx я в курсе, о чем написал выше.
Но конкретно твой пирожок (твоя ссылка) сыроват чтоб его кушать - с т.зр. поставленной задачи.

Usman http://bobobobo.wordpress.com/2008/02/03/getting-the-hwnd-and-hinstance-of-the-console-window/ Вот этот пирожок лучше (почти готовый). Но там много лишнего и чуть-чуть не хватает.
Пришлось на базе "лучшего из пирожков" изготовить свой:

Код: plaintext
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.
void CProga::Main()
{
...
  if (!Initialise()) {
    PThread::Sleep(100);  // workaround for race condition
    return;
  }
  char t[500];
  GetConsoleTitleA( t, 500 );     // retrieve the text of the title bar of the console window
  HWND hwndConsole = FindWindowA( NULL, t );
  HINSTANCE hInstance = (HINSTANCE)(LONG_PTR)GetWindowLong(hwndConsole, GWL_HINSTANCE);
  static const char* class_name = "DUMMY_CLASS";
  WNDCLASSEX wx = {};
  wx.cbSize = sizeof(WNDCLASSEX);
  wx.lpfnWndProc = WndProc;        // function which will handle messages
  wx.hInstance = hInstance;
  wx.lpszClassName = class_name;
  if ( RegisterClassEx(&wx) ) {
    HWND hwndWindow = CreateWindowEx( 0, class_name, "dummy_name", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
    cout << "Window Created" << "\n";
    // Enter regular message loop, to process messages for
    // our window.
    MSG msg;
    while( GetMessage( &msg, hwndWindow, 0, 0 ) )
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
...
  for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
      cout << "WM_COPYDATA" << endl;
      COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lparam;
      if (pcds->dwData == 1)
      {
        LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
        cout << lpszString << "(" << pcds->cbData << ")\n";
      }
      break;
  }
  return DefWindowProc( hwnd, message, wparam, lparam );
}



В принципе оно заработало.
Но возник вопрос.

Немного истории:

1. Изначально в оригинальном коде main() имела след. вид
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
void CProga::Main()
{
...
  if (!Initialise()) {
    PThread::Sleep(100);  // workaround for race condition
    return;
  }
  for (;;)
    PThread::Sleep(5000);
}


Пустой бесконечный цикл очевидно нужен для того чтобы приложение не закрывалось - вся начинка выполняется не в main().

2. Т.к. мне понадобилось "принимать файлы", то я в этот цикл воткнул "аля-таймер". Чего умел то и сумел.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
void CProga::Main()
...
  for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }
    if( (_access( "otherfile.txt", 0 )) != -1 ){
       //делай другие действия

  }



3. С учетом доработки на предмет ловли сообщений новоявленным окном получилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void CProga::Main()
...
    MSG msg;
    while( GetMessage( &msg, hwndWindow, 0, 0 ) )
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

 for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }
    if( (_access( "otherfile.txt", 0 )) != -1 ){
       //делай другие действия

  }


Выделенный кусок уже является бесконечным циклом.
Без него не работает обработка сообщений и вызывающее App тупо зависает.
Соответственно цикл что ниже (файлонаблюдатель) полностью выпадает из обращения.
По идее это не нужно если все перевести на язык SendMessage. Но хотелось бы такую возможность оставить.
Как?

Я возможно хочу и рыбку съесть и <...> сесть
но тем не менее:

Я не уверен что я во всех случаях смогу послать сообщение C-шному приложению.

Основной поток "обмена" в обе стороны идет между двумя приложениями.
1) C-консоль
2) VB-логический обработчик
Эти двое всегда запущены под одной и той же учетной записью.
Эта учетка может быть CURRENT_USER (As Application) либо SYSTEM (As NT Service).

Но есть еще например третье App (VB6) -оно всегда запущено под CURRENT_USER.
Потоковых сообщений (которых много) оно не посылает, но редкие из него посылаются.
Я не уверен, что CURRENT_USER может послать Message в сторону SYSTEM, наоборот кажется работает.

Но в любом случае на "переходный период" хотелось бы сохранить обе возможности.
Как?
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383391
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий773. С учетом доработки на предмет ловли сообщений новоявленным окном получилось:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
void CProga::Main()
...
    MSG msg;
    while( GetMessage( &msg, hwndWindow, 0, 0 ) )
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

 for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }
    if( (_access( "otherfile.txt", 0 )) != -1 ){
       //делай другие действия

  }


Выделенный кусок уже является бесконечным циклом.
Без него не работает обработка сообщений и вызывающее App тупо зависает.
Соответственно цикл что ниже (файлонаблюдатель) полностью выпадает из обращения.
По идее это не нужно если все перевести на язык SendMessage. Но хотелось бы такую возможность оставить.
Как?


А вот так сойдет? Оба функционала работают.
1) Файлы ловятся (овцы пока целы)
2) WM_COPYDATA ловится (волки будут сыты)
Подвохов нигде нет?
P.S. С-Proga завершается убиением консоли по методу "Kill". (м.б. это и неправильно но это факт)
Код: plaintext
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.
void CProga::Main()
{
...
  if (!Initialise()) {
    PThread::Sleep(100);  // workaround for race condition
    return;
  }

  DWORD dwThreadId, dwThrdParam = 1;
  HANDLE hThread;
  hThread = CreateThread(
   NULL,         // атрибуты безопасности по умолчанию
   0,            // размер стека используется по умолчанию
   ThreadFunc,   // функция потока
   &dwThrdParam, // аргумент функции потока
   0,            // флажки создания используются по умолчанию
   &dwThreadId); // возвращает идентификатор потока

  if (hThread == NULL)
  {
    cout << "CreateThread failed.\n"; 
  }
  else {
    cout << "CreateThread OK.\n"; 
    CloseHandle( hThread );
  }

  for (;;) {
    PThread::Sleep(500);
    ...
    if( (_access( "job.txt", 0 )) != -1 ){
       //читать файл
       //выполнять какой-то код
    }

}

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
      cout << "WM_COPYDATA" << endl;
      COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lparam;
      if (pcds->dwData == 1)
      {
        LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
        cout << lpszString << "(" << pcds->cbData << ")\n";
      }
      break;
  }
  return DefWindowProc( hwnd, message, wparam, lparam );
}

DWORD WINAPI ThreadFunc(LPVOID /*lpParam*/)
{
  char t[500];
  GetConsoleTitleA( t, 500 );     // retrieve the text of the title bar of the console window
  HWND hwndConsole = FindWindowA( NULL, t );
  HINSTANCE hInstance = (HINSTANCE)(LONG_PTR)GetWindowLong(hwndConsole, GWL_HINSTANCE);
  static const char* class_name = "DUMMY_CLASS";
  WNDCLASSEX wx = {};
  wx.cbSize = sizeof(WNDCLASSEX);
  wx.lpfnWndProc = WndProc;        // function which will handle messages
  wx.hInstance = hInstance;
  wx.lpszClassName = class_name;
  if ( RegisterClassEx(&wx) ) {
    HWND hwndWindow = CreateWindowEx( 0, class_name, "dummy_name", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
    cout << "Window Created" << "\n";
    // Enter regular message loop, to process messages for
    // our window.
    MSG msg;
    while( GetMessage( &msg, hwndWindow, 0, 0 ) )
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  return 0;
}


Просто с потоками не очень знаком, в VB с ними как то не очень.
Вот я создал поток, тем самым разблокировал свой "оригинальный" цикл, создал окно.
В конце делаю kill. Поток и окно убьются. hwndWindow по крайней мере после kill консоли =0, это немного успокаивает.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383452
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Как?
SetTimer() и проверяй файлы в обработчике WM_TIMER.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383489
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Dimitry, ну ты меня за школьника то не принимай (это я про лентяя).

http://bash.im/quote/424238
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383523
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovДмитрий77Как?
SetTimer() и проверяй файлы в обработчике WM_TIMER.

Спасибо, буду иметь ввиду. Пока оставлю как есть, возможно цикл/таймер не понадобится вообще.

Dimitry SibiryakovДмитрий77Dimitry, ну ты меня за школьника то не принимай (это я про лентяя).

http://bash.im/quote/424238

Не удержался, съязвил?
Ты ЗДЕСЬ не прав. И я тебе написал почему.
Ты меня отправил читать про CreateWindowEx (типа я не знаю что это такое).
Я в API достаточно хорошо разбираюсь и документации читать умею.
На приемы, используемые в C/C++ у меня рука не набита и опыта работы с C-шными ф-циями, понять работу которых порой нелегко даже после чтения документации у меня мало, здесь я спорить не буду.
А вопрос был поставлен:
Дмитрий77 Пример кода создания окна с процедурой WindowProc дашь?
Применительно к описываемой структуре C-приложения.
Прочтение даже очень внимательное голого описания CreateWindowEx ответа на поставленный вопрос не дает.

Usman дал правильный пример, отвечающий на поставленный вопрос.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383535
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А вот так сойдет? Оба функционала работают.
Подвохов нигде нет?
Вопрос был, правильно ли я имплементировал поток?
Не упустил ли чего? Не забыл ли чего?
Когда рука не набита, то подобную оплошность допустить очень легко. Поэтому прошу взглянуть.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383546
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Прочтение даже очень внимательное голого описания CreateWindowEx ответа на
поставленный вопрос не дает.
Вот только по моей ссылке не "голое описание функции CreateWindowEx()", а полное описание
процесса создания окна, включая готовый код о котором ты и просил. А в конце статьи -
ссылка на следующий шаг - написание цикла выборки сообщений.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383549
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Вопрос был, правильно ли я имплементировал поток?
поток в этой задаче не нужен. Обрабатывай WM_TIMER и WM_COPYDATA в одном месте.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383559
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВот только по моей ссылке не "голое описание функции CreateWindowEx()", а полное описание
процесса создания окна, включая готовый код о котором ты и просил. А в конце статьи -
ссылка на следующий шаг - написание цикла выборки сообщений.
Ну, там ничего не говорится ни про консоль (hInstance откуда брать), ни про HWND_MESSAGE, считаешь все это очевидным а поставленную задачу тривиальной? При ненабитой руке на такие штуки (консольное + окно + С++) это тем более не очевидно.
Ладно, забили, давай не будем ругаться. Но "форумных шуток-подколов" я не люблю и не понимаю, говорю об этом прямо.

ИзопропилДмитрий77Вопрос был, правильно ли я имплементировал поток?
поток в этой задаче не нужен. Обрабатывай WM_TIMER и WM_COPYDATA в одном месте.
Пожалуй так и сделаю, идею понял, тем более есть форма с готовым сабклассингом. Просто с API-таймером никогда не работал (всегда использовал Таймер-объект), поэтому данная мысль в голову не пришла.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383615
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSetTimer() и проверяй файлы в обработчике WM_TIMER.
ИзопропилОбрабатывай WM_TIMER и WM_COPYDATA в одном месте.
OK. Все получилось.
Но у меня маленький общий вопрос по сабклассингу:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
...
      return 0;
      break;
    case WM_TIMER:
...
      return 0;
      break;
  }
  return DefWindowProc( hwnd, message, wparam, lparam );
}


С break все понятно, он в C++ нужен чтоб выйти из switch, а с другой стороны позволяет выполнить единый код для нескольких сообщений:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
  switch( message )
  {
    case WM_COPYDATA:
    case WM_TIMER:
      //единый код для WM_COPYDATA и WM_TIMER
      break;
    case WM_...
  }


Мне не совсем понятно, а это видно из примеров на сайте майкрософт и из прочих
что люди норовят везде понатыкать return 0; да еще и break следом (кот. не сработает, т.к. уже вышли)

Просто на VB6 код обычно выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Public Function NewFormWindowProc _
 (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
  Select Case Msg
    Case WM_COPYDATA
       'код обработки WM_COPYDATA
    Сase WM_TIMER
       'код обработки WM_TIMER
    Case Else
  End Select
  
  NewFormWindowProc = CallWindowProc _
   (OldFormWindowProc, hwnd, Msg, wParam, lParam)
End Function



и лишь в редких случаях (когда это необходимо) надо в WindowProc вернуть что-то отличное от дефолта,
и приведенный фрагмент C++ на VB6 запишется так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Public Function NewFormWindowProc _
 (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 
  Select Case Msg
    Case WM_COPYDATA
       'код обработки WM_COPYDATA
       NewFormWindowProc = 0
       Exit Function
    Сase WM_TIMER
       'код обработки WM_TIMER
       NewFormWindowProc = 0
       Exit Function
    Case Else
  End Select
  
  NewFormWindowProc = CallWindowProc _
   (OldFormWindowProc, hwnd, Msg, wParam, lParam)
End Function

(что кажется дикостью, и хорошо еще если не повлияет на нормальное поведение)

Откуда такое стремление/необходимость/привычка и т.д. везде понатыкать return 0; ?
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383624
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 Откуда такое стремление/необходимость/привычка и т.д. везде понатыкать return 0; ? Тынц!
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383631
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Мне не совсем понятно, а это видно из примеров на сайте майкрософт и из
прочих что люди норовят везде понатыкать return 0; да еще и break следом (кот. не
сработает, т.к. уже вышли)
В каких именно примерах на сайте микрософт ты нашёл этот код?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383635
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 Откуда такое стремление/необходимость/привычка и т.д. везде понатыкать return 0; ?

Этому динозавру (WinAPI для собственно окон)- лет уже очень много. Где вернуть 0, где не 0, а где результат
DefWindowProc - рациональному объяснению не всегда поддаётся. Кто как привык - то так и пишет.
Если в каждой ветке писать явный return - не нужно помнить, что написали после switch - return 0 или return DefWindowProc(или чего ещё)

Дмитрий77Но у меня маленький общий вопрос по сабклассингу:
Не вижу сабклассинга. При сабклассинге(в смысле WinAPI) у конкретного экземпляра окна подменяется оконная функция и для необработанных сообщений вызывается не DefWindowProc, а предварительно сохранённая предыдущая.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383639
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВ каких именно примерах на сайте микрософт ты нашёл этот код?
Насчет return 0; например здесь:
Using Timers
Насчет
Код: plaintext
1.
2.
      return 0;
      break;


если Вы согласны со мной, что это чушь полная (просто подумал, вдруг какая-то C++ супер-фича, описанная в непрочитанной мной документации), то вряд ли я там найду.

А вот в приведенной выше ссылке (в почти вкусном пирожке):
http://bobobobo.wordpress.com/2008/02/03/getting-the-hwnd-and-hinstance-of-the-console-window/
автор просто этим злоупотребляет.

Usman Тынц!
Я почитал, но думаю, остановлюсь на варианте:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
  switch( message )
  {
    case WM_COPYDATA:
...
      break;
    case WM_TIMER:
...
      break;
  }
  return DefWindowProc( hwnd, message, wparam, lparam );
}



Никогда я в VB не злоупотреблял
Код: vbnet
1.
2.
3.
    Сase...
...
       Exit Function


(кроме случаев когда это НАДО согласно описанию и желаемым результатам)
И меня это не подводило.
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383640
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилГде вернуть 0, где не 0, а где результат DefWindowProc - рациональному
объяснению не всегда поддаётся.
Почему не поддаётся? Если сообщение обрабатывается самой оконной функцией, то, что она
обязана вернуть - написано в справке. Потому что именно это значение будет возвращено
SendMessage(). И таки да, некоторые странные люди это возвращённое значение проверяют
и/или используют. Включая саму систему. И именно поэтому, во всех случаях, когда
вызывается DefWindowProc(), её возвращённое значение должно и возвращаться оконной
функцией. Иначе в приложении могут быть весьма интересные глюки, которые некоторые новички
принимают за глюки системы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как передать сообщение (SendMessage) C-шному приложению (консоль).
    #38383643
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovнаписано в справке
это и есть не поддаётся
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как передать сообщение (SendMessage) C-шному приложению (консоль).
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]