Die eigentliche Startdatei eines Projektes wird normalerweise nicht editiert. Über die Projektverwaltung hat diese den Name der EXE-Datei mit der Endung CPP. Diese Datei sollte ungefähr so aussehen wie der folgende Programmauszug. In diese Datei ist der als zum Einfügen gekennzeichnete Teil einzufügen.
Sofern das Programm bisher einmal gestartet wurde, wird ein Mutex erstellt. Bei nochmaligen Start ist dieser schon vorhanden und der Programmablauf kann abgebrochen werden.
#include <vcl.h>
#pragma hdrstop
USERES("MP3Player.res");
USEFORM("UnitMain.cpp", Main);
USEFORM("UnitOptionen.cpp", Optionen);
USEFORM("UnitCopy.cpp", Copyright);
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR cmdLine, int)
{
try
{
//*********** Eingfügen **********************
HANDLE hMutex=OpenMutex(MUTEX_ALL_ACCESS,0,"MeinProgramm");
if(!hMutex)
{
hMutex=CreateMutex(0,0,"MeinProgramm");
}
else
{
ShowMessage("Das Programm läuft bereits");
return 0;
}
//********** Ende Einfügen ******************
Application->Initialize();
Application->CreateForm(__classid(TMain), &Main);
Application->CreateForm(__classid(TOptionen), &Optionen);
Application->CreateForm(__classid(TCopyright), &Copyright);
Application->Run();
//*********** Eingfügen **********************
ReleaseMutex(hMutex);
//********** Ende Einfügen ******************
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
Soll das bereits laufende Programm in den Vordergrund gebracht werden, ist die Zeile ShowMessage("Das Programm läuft bereits"); mit folgendem Programmcode zu tauschen:
HWND hWnd=FindWindow(0,"Name_des_Programmfensters"); SetForegroundWindow(hWnd);
Name_des_Programmfensters ist durch den Fensternamen zu ersetzen, der dem Fenster entspricht, welches angezeigt werden soll. Ggf. muss das Fenster, wenn der Name nicht bekannt ist oder nur teilweise bekannt ist gesucht werden
Dieser Fall tritt üblicherweise ein, wenn die in der Kommandozeile übergebenen Daten an das schon laufende Programm zu übergeben sind. Dazu werden:
Zunächst die Datenübergabe per WM_COPYDATA. Dies wird auch in der obigen Startdatei des Projektes durchgeführt. Beispielsweise nachdem das Fenster in den Vordergrund gebracht wurde:
HWND hWnd=FindWindow(0,"Name_des_Programmfensters");
if(strlen(cmdLine)!=0)
{
COPYDATASTRUCT cds;
cds.dwData=NULL;
cds.cbData=strlen(cmdLine)+1;
cds.lpData=cmdLine;
SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cds);
}
Dadurch werden die Daten der Kommandozeile das schon laufende Programm gesandt. Nun muss das Programm diese empfangen können. Dazu muss es auf die Nachricht WM_COPYDATA reagieren. Hierzu ist es zunächst erforderlich, dass diese Nachricht in die Botschaftsbearbeitungsroutine des FORMULARS mit aufgenommen wird. In der Headerdatei des Formulars, welches die Nachricht empfangen soll. Ist folgende Deklaration aufzunehmen:
class TMain : public TForm
{
__published: // Von der IDE verwaltete Komponenten
....
private: // Anwenderdeklarationen
void __fastcall WmCopyData(TWMCopyData& Message);
public: // Anwenderdeklarationen
__fastcall TMain(TComponent* Owner);
// Messagehandling deklarieren:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_COPYDATA, TWMCopyData, WmCopyData)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TMain *Main;
//---------------------------------------------------------------------------
#endif
Der Codeausschnitt zeigt die Headerdatei. Die sieht je nach Formular anders aus, jedoch die Struktur ist immer gleich. In den public Abschnitt ist der rot dargestellte Code aufzunehmen. Dann reagiert das Formular auf die Nachricht WM_COPYDATA. Jedoch muss nun nur noch die Routine geschrieben werden, die die Daten entgegen nimmt.Diese Routine wurde oben in dem private Abschnitt deklariert. Nun muss sie noch in der CPP-Datei programmiert werden:
void __fastcall TMain::WmCopyData(TWMCopyData& Message)
{
String slCmdLine=(char*)Message.CopyDataStruct->lpData;
//mach was mit den Daten
}
//---------------------------------------------------------------------------