Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.188.152.162] |
|
Сообщ.
#1
,
|
|
|
Ребята, возник вопрос.
Хочу при запуске программы проверить, запущена она или нет, знаю что можно сделать, но не знаю как. Помогите плиз |
Сообщ.
#2
,
|
|
|
Я делаю так:
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\% |
Сообщ.
#3
,
|
|
|
Имхо, проще file-mapping использовать. И гораздо меньше ресурсов потребуется.
|
Сообщ.
#4
,
|
|
|
erpup: а по конкретнее можна?
и ещё по какому событию делать проверку? Говорят, что в Билдере есть встроенный механизм, но только что за механизм и как им пользоваться - без понятия |
Сообщ.
#5
,
|
|
|
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); |
Сообщ.
#6
,
|
|
|
to michl_m: спасибо, и всё таки подскажите по какому событию обрабатывать поиск?
Нужно, если прога уже запущена, не запускать её, Форм Шоу не подходит однозначно |
Сообщ.
#7
,
|
|
|
Лучше всего исп. второй вариант предложенный 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; } |
Сообщ.
#8
,
|
|
|
Зачем что-то создавать/искать? Имхо, гораздо проще создать поместить счетчик выполняемых экземпляров в общий сегмент:
#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; } Вот и все. |
Сообщ.
#9
,
|
|
|
Ребята, всем большое спасибо, за то что уделили внимание и поделились знаниями.
|
Сообщ.
#10
,
|
|
|
В билдере я так и не нашел как сделать шаред секцию, так как нет ничего пожожего на #pragma data_seg
|
Сообщ.
#11
,
|
|
|
А что, в билдере нет директив компилятора?? Я вообще-то с ним не работал никогда, но думаю, что должно быть что-то подобное. :-/
|
Сообщ.
#12
,
|
|
|
Да #pragm всяких навалом, но вот связанной с привязкой данных нет
Ладно eprup айда закругляемся а то оффтопик пошел. |
Сообщ.
#13
,
|
|
|
2: Han, zAg
Второй вариант действительно, наверное, быстрее работает. |
Сообщ.
#14
,
|
|
|
2eprup: хорошее решение! Я как -то и не задумывался, что shared-секции можно использовать не только в DLL.
В C++ Builder shared тоже делается через #pragma, но не помню, как... |
Сообщ.
#15
,
|
|
|
Честно признаться, этот пример практически содран у Рихтера. Я раньше тоже через Shared делал, но немного через ....., ;-)
|