
różne
Umieszczanie programu w programie, czyli coś w rodzaju instalatora). Przed zamknięciem program pierwszy wypakuje program drugi i go uruchomi, a potem jak pisałem...

Cyfrowy Baron napisał(a):Do restartu programu potrzebowałbyś drugiego programu [...]
HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS,FALSE,"twoja_aplikacja.exe_restart");
if(hEvent)
{
DWORD res = WaitForSingleObject(hEvent,INFINITE);
if(res != WAIT_OBJECT_0)
{
/* coś poszło nie tak, zamykasz aplikację */
return -1;
}
CloseHandle(hEvent);
}
/* klasa pomocnicza */
class signal_event_at_end
{
HANDLE m_event;
public:
signal_event_at_end(HANDLE event)
:m_event(event) {}
~signal_event_at_end()
{
if(!m_event)return;
SetEvent(m_event);
CloseHandle(m_event);
}
};
...
hEvent = CreateEvent(NULL,FALSE,FALSE,"twoja_aplikacja.exe_restart");
if(hEvent)
{
ShellExecute(NULL,"open","twoja_aplikacja.exe",NULL,NULL,SW_SHOW);
static signal_event_at_end tmp(hEvent);
/* zamykasz aplikację */
}

View source) tworzysz mutex i podpinasz go pod funkcję WaitForSingleObject://---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "nazwa_aplikacji.exe_restart"); /* nazwa jest dowolna, tutaj: "nazwa_aplikacji.exe_restart" */
if(!hMutex) hMutex = CreateMutex(0, 0, "nazwa_aplikacji.exe_restart"); /* nazwa taka sama jak wyżej więc tutaj: "nazwa_aplikacji.exe_restart" */
else
{
if(WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0)
{
return -1;
}
}
try
{
Application->Initialize();
SetApplicationMainFormOnTaskBar(Application, true);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShellExecute(NULL,"open","nazwa_aplikacji.exe",NULL,NULL,SW_SHOW); /* nazwa_aplikacji.exe to nazwa pliku programu */
Close();
}
//---------------------------------------------------------------------------//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
THandle h = (int)CreateSemaphore(NULL, 0, 1, "nazwa_aplikacji.exe.semaphore"); /* nazwa jest dowolna, tutaj: "nazwa_aplikacji.exe_semaphore" */
if((h != 0) && (GetLastError() == ERROR_ALREADY_EXISTS))
{
CloseHandle((void *)h);
ShowMessage("Ten program jest już uruchomiony!");
Application->Terminate();
}
}
//---------------------------------------------------------------------------

Nie bardzo jednak rozumiem czemu ma służyć ta klasa pomocnicza, bez niej kod również działa prawidłowo.
Pozwolę sobie przedstawić podobne rozwiązanie oparte na mutexach:

Ale na tym rozwiązaniu nie otworzysz dwóch instancji aplikacji...



Nie wiem czy dobrze zrozumiałem. Twierdzisz, że nie uruchomię dwóch kopii tego samego programu?!
- Kod: Zaznacz cały
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "nazwa_aplikacji.exe_restart");
if(!hMutex) hMutex = CreateMutex(0, 0, "nazwa_aplikacji.exe_restart");
else
{
if(WaitForSingleObject(hMutex, INFINITE) != WAIT_OBJECT_0)
{
return -1;
}
}
...
return 0;
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(modify == true)
{
int mbResult2 = MessageBox(NULL,
"Dokonano zmian. Czy chcesz zapisać swoją pracę?",
"Zakończ", MB_YESNOCANCEL | MB_ICONQUESTION);
if(mbResult2 == IDNO)
{
Action = caFree; // odblokowuje zamykanie jeżeli zablokowane
return;
}
if(mbResult2 == IDCANCEL)
{
Action = caNone; // blokuje zamknięcie formularza
return;
}
if(mbResult2 == IDYES)
{
MessageBox(NULL,"Aby zapisać dotychczasowy efekt pracy użyj funkcji Zapisz w lewym dolnym rogu okna programu.",
"Zakończ", MB_OK | MB_ICONINFORMATION);
LabeledEdit1->Color=clYellow;
Action = caNone;
return;
}
}
else Action = caFree;
}
Pewnie znowu zapomniałem dodać bardzo ważnego szczegółu mianowicie program posiada blokade uruchomienia kilku kopii naraz

Pomyliłem się, dwie uruchomisz, ale większej ilości już nie.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "twoja_aplikacja.exe_restart");
if(!hMutex) hMutex = CreateMutex(0, 0, "twoja_aplikacja.exe_restart");
else
{
HWND hWnd = FindWindow("TForm1", NULL); /* nazwa klasy formularz głównego powinna być unikatowa, tutaj TForm1 */
if(hWnd)
{
WaitForSingleObject(hMutex, INFINITE);
ShowMessage("Program jest już uruchomiony");
Application->Terminate();
}
}
try
{
Application->Initialize();
SetApplicationMainFormOnTaskBar(Application, true);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, 0, "twoja_aplikacja.exe_restart");
if(!hMutex) hMutex = CreateMutex(0, 0, "twoja_aplikacja.exe_restart");
else
{
WaitForSingleObject(hMutex, INFINITE);
ShowMessage("Program jest już uruchomiony");
Application->Terminate();
}
Application->Initialize();
SetApplicationMainFormOnTaskBar(Application, true);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
ReleaseMutex(hMutex);
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
|
|
ShowMessage("Program jest już uruchomiony");
Application->Terminate();ShowMessage("Program jest już uruchomiony");
Application->Terminate();
Powrót do Ogólne problemy z programowaniem
Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości