На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Как передать сообщение другому приложению?
    Каков будет код для передачи пользовательского сообщения другому приложению о котором первому известно только название исполняемого файла?И каков будет код получения и обработки принимающим приложением?То есть стоит задача передать сообщение от одного приложения другому и зафиксировать прием сообщения отображением MessageBox(сообщение полученоMB_OK).
      Это системное программирование, IPC
        Насколько я вижу ветка называется и win API.А вызов функции sendmessage или postmessage это и есть windows api.И в чем я заблуждаюсь?
          CreateToolhelp32Snapshot() + Process32First()/Process32Next() + OpenProcess() + QueryFullProcessImageName()
          Ну и не забыть про CloseHandle()
            Джеффри Рихтер расписал способы межпроцессного общения
            Цитата
            Взаимодействие между процессами
            Потоки одного процесса не имеют доступа к адресному пространству другого
            процесса. Однако существуют механизмы для передачи данных между процессами.

            http://library.tsilikin.ru/%D0%A2%D0%B5%D1...2%20Windows.pdf

            Тебе, очевидно, более подойдёт инфа на стр 14.
            Цитата
            Сообщения в Windows (оконные сообщения)
              Пусть ТС сначала определится, что ему надо. Как связать имя исполняемого файла с процессом, объяснено. Перечислить нитки процесса из того же снапшота CreateToolhelp32Snapshot() дело двух кликов мышью по справочнику Process32First(). За посылку сообщений в нить говорилось в соседней теме.
              Если же нужно окно, то искать процесс вообще не нужно, нужно искать окно. Перечислить все окна верхнего уровня EnumWindows(), в каллбаке которого EnumWindowsProc сравнивать нитку-владельца с результатом GetWindowThreadProcessId(). Как вариант – перебрать все окна нитки EnumThreadWindows(). Как удобнее, ябеспонятия. ИМХО искать окна неблагодарное занятие, если о них ничего не известно.
              Сообщение отредактировано: Qraizer -
                Цитата izumov @
                Каков будет код для передачи пользовательского сообщения другому приложению о котором первому известно только название исполняемого файла?И каков будет код получения и обработки принимающим приложением?

                Оба приложения твои? Что конкретно нужно передать? WM_-сообщение или бинарные данные? Или просто дёрнуть логику "отдал-принял" любым событием? В последнем случае подойдёт самый обычный Event: https://learn.microsoft.com/en-us/windows/w...pi-createeventa

                Цитата DrUnkard @
                Джеффри Рихтер расписал способы межпроцессного общения

                Майкрософт их расписал, полагаю, много раньше Рихтера: https://learn.microsoft.com/en-us/windows/w...synchronization
                  Цитата B.V. @
                  Майкрософт их расписал, полагаю, много раньше Рихтера

                  И чо?
                  Рихтер сам консультировал Микрософт.
                  Я дал человеку текст на русском языке, шо, заведомо, читабельнее.
                    Цитата DrUnkard @
                    Я дал человеку текст на русском языке, шо, заведомо, читабельнее.

                    Согласен. К тому же межпроцессное взаимодействие будет еще и более православным! :)
                      :angry: Нате на нитках. Ожидающее приложение:
                      ExpandedWrap disabled
                        #include <windows.h>
                        #include <iostream>
                        #include <functional>
                        #include <stdexcept>
                        #include <thread>
                        #include <mutex>
                         
                        UINT  usrMsg;
                        MSG   msg;
                        DWORD msgThread = 0;
                         
                        class Guard
                        {
                          std::function<void(void)> fn;
                         
                        public:
                          Guard(const std::function<void(void)>& f): fn(f) {}
                         ~Guard() { fn(); }
                        };
                         
                        std::mutex modal;
                         
                        void wndProc(UINT uMsg, WPARAM, LPARAM lParam)
                        {
                          if (uMsg == usrMsg) modal.lock(), MessageBox(NULL, "сообщение получено", "threadClient", MB_OK), modal.unlock();
                          if (lParam == 1) PostQuitMessage(0);
                        }
                         
                        using namespace std::literals;
                         
                        void workThread(void) try
                        {
                          msgThread = GetCurrentThreadId();
                         
                          HMODULE   kernel(LoadLibrary("KernelBase.dll"));
                          Guard     freeKernel([&]{ FreeLibrary(kernel); });
                          HRESULT (*SetThreadDescription)(HANDLE, PCWSTR) = nullptr;
                         
                          if (kernel == NULL)                 throw std::runtime_error("KernelBase.dll isn't load"s);
                          SetThreadDescription = reinterpret_cast<HRESULT (*)(HANDLE, PCWSTR)>(GetProcAddress(kernel, "SetThreadDescription"));
                          if (SetThreadDescription == nullptr)throw std::runtime_error("SetThreadDescription() isn't found"s);
                         
                          if (FAILED(SetThreadDescription(GetCurrentThread(), L"working message thread")))
                            throw std::runtime_error("SetThreadDescription() fails"s);
                         
                          while (GetMessage(&msg, reinterpret_cast<HWND>(-1), 0, 0))
                            wndProc(msg.message, msg.wParam, msg.lParam);
                        }
                        catch(const std::exception& exc)
                        {
                          std::cerr << exc.what() << std::endl;
                        }
                         
                        int main()
                        {
                          usrMsg = RegisterWindowMessage("Message for client");
                          if (usrMsg == 0)
                            return std::cout << "RegisterWindowMessage() fails",
                                   1;
                         
                          INPUT_RECORD inp;
                          DWORD        readed;
                          std::thread  working(workThread);
                         
                          for (;;)
                          {
                            if (ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &inp, 1, &readed) == 0) break;
                            if (inp.EventType == KEY_EVENT &&
                                inp.Event.KeyEvent.bKeyDown == TRUE && inp.Event.KeyEvent.uChar.AsciiChar == '\x1B' &&
                               (inp.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED |
                                                                        RIGHT_ALT_PRESSED| RIGHT_CTRL_PRESSED|
                                                                        ENHANCED_KEY     | SHIFT_PRESSED)) == 0) break;
                          }
                          while (msgThread == 0 || !modal.try_lock()) Sleep(0);
                          PostThreadMessage(msgThread, WM_COMMAND, 0, 1);
                          modal.unlock();
                          working.join();
                         
                          return 0;
                        }
                      Посылающее приложение.
                      ExpandedWrap disabled
                        #include <windows.h>
                        #include <tlhelp32.h>
                        #include <stdexcept>
                        #include <iostream>
                         
                        using namespace std::literals;
                         
                        template <typename H, HANDLE Inv = NULL>
                        class Resource
                        {
                          H handle;
                         
                        public:
                          explicit Resource(H h): handle(h) { if (handle == Inv) throw std::runtime_error("NULL handle"s); }
                          Resource(const Resource&)       = delete;
                          void operator=(const Resource&) = delete;
                         
                          operator H() const { return handle;       }
                         
                        protected:
                         ~Resource() {}
                        };
                         
                        template <HANDLE Inv = NULL>
                        class Handle: public Resource<HANDLE, Inv>
                        {
                        public:
                          explicit Handle(HANDLE h): Resource(h) {}
                         ~Handle() { CloseHandle(*this); }
                        };
                         
                        class Hmodule: public Resource<HMODULE>
                        {
                        public:
                          explicit Hmodule(HMODULE h): Resource(h) {}
                         ~Hmodule() { FreeLibrary(*this); }
                        };
                         
                        class Wchar: public Resource<wchar_t*>
                        {
                        public:
                          explicit Wchar(wchar_t *h): Resource(h) {}
                         ~Wchar() { LocalFree(*this); }
                        };
                         
                        int main() try
                        {
                          UINT usrMsg = RegisterWindowMessage("Message for client");
                         
                          if (usrMsg == 0)
                            return std::cout << "RegisterWindowMessage() fails",
                                   1;
                         
                          Handle<INVALID_HANDLE_VALUE> snapShot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0));
                          PROCESSENTRY32 proc = { sizeof(proc) };
                          DWORD        procId = 0;
                          Hmodule   kernel(LoadLibrary("KernelBase.dll"));
                          HRESULT (*GetThreadDescription)(HANDLE, PWSTR*) = nullptr;
                         
                          if (kernel == NULL)                 throw std::runtime_error("KernelBase.dll isn't load"s);
                          GetThreadDescription = reinterpret_cast<HRESULT (*)(HANDLE, PWSTR*)>(GetProcAddress(kernel, "GetThreadDescription"));
                          if (GetThreadDescription == nullptr)throw std::runtime_error("GetThreadDescription() isn't found"s);
                         
                          if (Process32First(snapShot, &proc) != FALSE)
                            do
                              if (proc.szExeFile == "threadClient.exe"s)
                              {
                                procId = proc.th32ProcessID;
                                break;
                              }
                            while (Process32Next(snapShot, &proc) != FALSE);
                          if (procId == 0) throw std::runtime_error("threadClient.exe not found"s);
                         
                          THREADENTRY32 thread = { sizeof(thread) } ;
                          DWORD       threadId = 0;
                         
                          if (Thread32First(snapShot, &thread) != FALSE)
                            do
                            {
                              if (thread.th32OwnerProcessID != procId) continue;
                         
                              Handle<> threadClient(OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, thread.th32ThreadID));
                              Wchar    buffer([&]{ wchar_t *buffer; GetThreadDescription(threadClient, &buffer); return buffer; }());
                         
                              if (std::wstring(buffer) == L"working message thread"s)
                              {
                                threadId = thread.th32ThreadID;
                                break;
                              }
                            } while (Thread32Next(snapShot, &thread) != FALSE);
                          if (threadId == 0) throw std::runtime_error("working message thread of threadClient.exe not found"s);
                          PostThreadMessage(threadId, usrMsg, 0, 0);
                        }
                        catch(const std::exception& exc)
                        {
                          std::cerr << exc.what() << std::endl;
                        }
                      Писано на коленке, так что плз без претензий. Ожидающее выходит по ESC.
                      Как найду время, напишу и запосчу на окнах.

                      Добавлено
                      P.S. Забыл пояснить. По идее ожидающее называется threadClient.exe. Если это не так, то переименуйте или измените искомое посылающим имя.

                      Добавлено
                      Нате на окнах. Ожидающее приложение:
                      ExpandedWrap disabled
                        #include <windows.h>
                         
                        #define IDM_QUIT 101
                        #define ICON_ID  1
                         
                        WNDCLASS wndClass;
                        MSG      msg;
                        HWND     hWnd;
                        UINT     usrMsg, trayMsg;
                        HMENU    hMenu;
                         
                        BOOL CreateOwnMenu()
                        {
                          if ((hMenu = CreatePopupMenu()) == NULL)
                            return FALSE;
                          if (!AppendMenu(hMenu, MF_STRING, IDM_QUIT, "stop it"))
                            return DestroyMenu(hMenu),
                                   FALSE;
                          return TRUE;
                        }
                         
                        NOTIFYICONDATA nid;
                         
                        LRESULT CALLBACK wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                        {
                          POINT curPos;
                         
                          switch (uMsg)
                          {
                            case   WM_CREATE:
                                   usrMsg = RegisterWindowMessage("Message for client");
                                   trayMsg= RegisterWindowMessage("Notyfy message");
                                   if (usrMsg == 0)      return -1;
                                   if (trayMsg== 0)      return -1;
                                   if (!CreateOwnMenu()) return -1;
                         
                                   nid.cbSize = sizeof(nid);
                                   nid.hWnd   = hWnd;
                                   nid.uID    = ICON_ID;
                                   nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
                                   nid.uCallbackMessage = trayMsg;
                                   nid.hIcon  = LoadIcon(NULL, IDI_WARNING);
                                   strcpy(nid.szTip, "appClient");
                                   Shell_NotifyIcon(NIM_ADD, &nid);
                                   return 0;
                            case   WM_CLOSE:
                                   DestroyMenu(hMenu);
                                   Shell_NotifyIcon(NIM_DELETE, &nid);
                                   DestroyWindow(hWnd);
                                   return 0;
                            case   WM_DESTROY:
                                   PostQuitMessage(0);
                                   return 0;
                            default:
                                   if (uMsg == usrMsg) MessageBox(NULL, "сообщение получено", "appClient", MB_OK);
                                   if (uMsg == trayMsg)
                                     switch(lParam)
                                     {
                                       DWORD retCmd;
                         
                                       case WM_LBUTTONDOWN:
                                       case WM_RBUTTONDOWN:
                                            GetCursorPos(&curPos);
                                            SetForegroundWindow(hWnd);
                                            retCmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, curPos.x, curPos.y,
                                                                    0, hWnd, NULL);
                                            switch(retCmd)
                                            {
                                              case IDM_QUIT:
                                                   PostMessage(hWnd, WM_CLOSE, 0, 0);
                                                   break;
                                              default:
                                                   break;
                                            }
                                     }
                                   return DefWindowProc(hWnd, uMsg, wParam, lParam);
                           }
                        }
                         
                        int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int)
                        {
                          wndClass.lpfnWndProc  = wndProc;
                          wndClass.cbClsExtra   = 0;
                          wndClass.cbWndExtra   = 0;
                          wndClass.hInstance    = GetModuleHandle(NULL);
                          wndClass.hIcon        = LoadIcon       (NULL, IDI_WARNING);
                          wndClass.hCursor      = LoadCursor     (NULL, IDC_ARROW);
                          wndClass.hbrBackground= reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
                          wndClass.lpszMenuName = NULL;
                          wndClass.lpszClassName= "appClient class window";
                          if (RegisterClass(&wndClass) == 0)                                 return 1;
                          if ((hWnd = CreateWindow(wndClass.lpszClassName, "appClient", WS_POPUP, 0, 0, 0, 0,
                                          NULL, NULL, GetModuleHandle(NULL), NULL)) == NULL) return 1;
                          ShowWindow(hWnd, SW_HIDE);
                         
                          while (GetMessage(&msg, 0, 0, 0))
                          {
                            TranslateMessage(&msg);
                            DispatchMessage(&msg);
                          }
                          return 0;
                        }
                      Посылающее приложение.
                      ExpandedWrap disabled
                        #include <windows.h>
                        #include <iostream>
                         
                        int main()
                        {
                          HWND hWnd = FindWindow("appClient class window", "appClient");
                          UINT usrMsg = RegisterWindowMessage("Message for client");
                         
                          if (hWnd == NULL)
                            return std::cout << "appClient window not found",
                                   1;
                          if (usrMsg == 0)
                            return std::cout << "RegisterWindowMessage() fails",
                                   1;
                         
                          SendMessage(hWnd, usrMsg, 0, 0);
                          return 0;
                        }
                      Ожидающее падает в трей и выходит по команде оттуда. Посылающее ищет окно класса "appClient class window" с заголовком "appClient". Оно скрыто, но это пофик. Если запустите несколько экземпляров ожидающего, окна будут дублированы. Каким экземпляром будут обрабатываться сообщения, афикъегознает.
                      Сообщение отредактировано: Qraizer -
                        Цитата Qraizer @
                        Если запустите несколько экземпляров ожидающего, окна будут дублированы.
                        P.S. То же, прочем и для threadClient.exe.
                        Сообщение отредактировано: Qraizer -
                          Мое затруднение состоит в том что я не могу определить место нахождения wndProc в моем проекте сделанном в visual studio по шаблону CppCLR_WinForms_GUI.
                          Могли бы Вы мне подсказать в каком месте проекта я могу увидеть эту функцию и скорректировать ее?
                          Сообщение отредактировано: izumov -
                            А просто повесить на окно дополнительную функцию-фильтр не катит?
                            ExpandedWrap disabled
                              oldWindowProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, &newWndProc);
                            А после в новой функции вызываете старую, отправляя ей не обрабатываемые сообщения
                            ExpandedWrap disabled
                              //Вместо return DefWindowProc(hWnd, uMsg, wPar, lPar);
                              return CallWindowProc(oldWindowProc, hWnd, uMsg, wPar, lPar);
                            Сообщение отредактировано: macomics -
                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0435 ]   [ 16 queries used ]   [ Generated: 26.04.24, 20:46 GMT ]