На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Запущена программа или нет?
    Ребята, возник вопрос.
    Хочу при запуске программы проверить, запущена она или нет, знаю что можно сделать, но не знаю как.
    Помогите плиз
      Я делаю так:

      BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
      {  static char szTemp[80];
         CString str;

        GetWindowText(hwnd, szTemp, sizeof(szTemp));
        str=szTemp;
        if(str.Find("твоя прога")!=-1)
        hwndApp=hwnd;
        return (hwnd >= 0) ? TRUE : FALSE;
      }

      BOOL xxx::FirstInstance()
      {
      // CString strCaption;
      // strCaption.LoadString(AFX_IDS_APP_TITLE);

       EnumWindows(EnumWindowsProc, NULL);
       
      CWnd* pwndFirst = CWnd::FromHandle(hwndApp);
      if (pwndFirst)
      {  
      CWnd* pwndPopup = pwndFirst->GetLastActivePopup();
      pwndFirst->SetForegroundWindow();
      if (pwndFirst->IsIconic())
        pwndFirst->ShowWindow(SW_SHOWMAXIMIZED);
      if (pwndFirst != pwndPopup)
       pwndPopup-SetForegroundWindow();
      return FALSE;
      }
      else
      {
       return TRUE;
      }

      }

      BOOL xxx::InitInstance()
      {  if (!FirstInstance())  return FALSE;
      .
      .
      работает на все 100\%
        Имхо, проще file-mapping использовать. И гораздо меньше ресурсов потребуется.
          erpup:  а по конкретнее можна?
          и ещё по какому событию делать проверку?
          Говорят, что в Билдере есть встроенный механизм, но только что за механизм и как им пользоваться - без понятия
            1. Поискать главное окно. У него есть заголовок.
            Тогда:
            HWND hWndFind = FindWindow(NULL, "My program");
            if ( hWndFind != NULL )
            {
            ..программа уже запущена.
            }

            2. Создать любой именованый объект ядра. А затем проверять, не создан ли.
            HANDLE hEv =
            CreateEvent(NULL, FALSE, FALSE, "Special_for_one_instance ");
            if ( GetLastError() == ERROR_ALREADY_EXISTS )
            {
            //..программа уже запущена.

            }
            При окончании программы не забуть CloseHandl(hEv);




              to michl_m: спасибо, и всё таки подскажите по какому событию обрабатывать поиск?
              Нужно, если прога уже запущена, не запускать её, Форм Шоу не подходит однозначно
                Лучше всего исп. второй вариант предложенный michl_m:
                Проверку делай сразу после  WinMain. Делается так:

                WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR pStr, int)
                {
                     try{
                           Application->Initialize();//Этот вызов вообще можно выкинуть - толку никакого
                           Application->Title = "Single App";

                           HANDLE hEv = CreateEvent(NULL, FALSE, FALSE, "Special_for_one_instance ");
                           if ( GetLastError() == ERROR_ALREADY_EXISTS )
                             MessageBox(NULL,"Другой экземпляр приложения уже работает!",Application->Title.c_str(),MB_OK|MB_ICONSTOP);
                                 goto label_exit;//из try лучше выходить так
                           {

                           try{
                //теперь можно создавать формы
                                 Application->CreateForm(...);
                                 Application->CreateForm(...);

                                 Application->Run();//поехали!

                           }      
                           catch (Exception &exception)
                           {
                                 Application->ShowException(&exception);
                           }

                     label_exit:

                     }
                     __finally{
                           CloseHandle(hEv);
                     }

                     return 0;
                }
                  Зачем что-то создавать/искать? Имхо, гораздо проще создать поместить счетчик выполняемых экземпляров в общий сегмент:

                  #pragma data_seg("SharedSeg")
                  LONG g_uAppCount = 0;
                  #pragma data_seg()

                  #pragma comment(linker, "/Section:SharedSeg,RWS")

                  int APIENTRY WinMain(HINSTANCE hInstance,
                                      HINSTANCE hPrevInstance,
                                      LPSTR     lpCmdLine,
                                      int       nCmdShow)
                  {
                  if (g_uAppCount)  // если счетчик > 0 - не запускать
                     return 0;

                  ::InterlockedExchangeAdd((LPLONG)&g_nInstanceCount, 1); // увеличить значение счетчика на 1

                  // ...

                  InterlockedExchangeAdd((LPLONG)&g_nInstanceCount, -1);  // уменьшить значение счетчика на 1
                  return 0;
                  }

                  Вот и все.
                    Ребята, всем большое спасибо, за то что уделили внимание и поделились знаниями.
                      В билдере я так и не нашел как сделать шаред секцию, так как нет ничего пожожего на #pragma data_seg   :(
                        А что, в билдере нет директив компилятора?? Я вообще-то с ним не работал никогда, но думаю, что должно быть что-то подобное. :-/
                          Да #pragm всяких навалом, но вот связанной с привязкой данных нет :(
                          Ладно eprup айда закругляемся а то оффтопик пошел.
                            2: Han, zAg
                            Второй вариант действительно, наверное, быстрее работает.
                              2eprup: хорошее решение! Я как -то и не задумывался, что shared-секции можно использовать не только в DLL.
                              В C++ Builder shared тоже делается через #pragma, но не помню, как...
                                Честно признаться, этот пример практически содран у Рихтера. :) Я раньше тоже через Shared делал, но немного через ....., ;-)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0311 ]   [ 17 queries used ]   [ Generated: 25.04.24, 15:07 GMT ]