Board index » cppbuilder » ParamStr() and CreateMutex problem

ParamStr() and CreateMutex problem


2004-09-01 01:38:52 PM
cppbuilder25
Hello,
My application allows multiple pages to open using TTabSheet(PageControl).
The below code succesfully opens a file from Explorer on left/right click
or from WS_FTP if set as default editor. However, if I multi-select files,
each file opens in a new instance of my appication. I tried limiting my
instances using CreateMutex but it limits me to opening one file only. How
do I prevent my application from multi-executing on multi-selecting files
and instead point the additional files to the already opened instance of
my application?
void __fastcall TMainForm::FormShow(TObject *Sender)
{
if(ParamCount()>0){
AnsiString filename = ParamStr(1);
if(FileExists(filename)) {
file = filename;
captitle = ExtractFileName(file);
IniMemo(Sender);
memo->Tag = 1;
sheet->Hint = ExpandFileName(file);
}
}
}
void __fastcall TMainForm::IniMemo(TObject *Sender)
{
sheet = new TTabSheet(PageControl1);
sheet->Caption = captitle;
sheet->PageControl = PageControl1;
gutter = new TPlusGutter(sheet);
gutter->Parent = sheet;
gutter->Align = alLeft;
gutter->ParagraphNumbers = true;
gutter->Visible = iLineNumbers;
gutter->LineNumbers = iLineNumbers;
gutter->Font->Color = cl3DDkShadow;
memo = new TPlusMemo(sheet);
memo->Parent = sheet;
memo->Align = alClient;
memo->Lines->LoadFromFile(file);
memo->Modified = false;
}
Roger.
 
 

Re:ParamStr() and CreateMutex problem

"Roger Remacle" < XXXX@XXXXX.COM >wrote in message
Quote
if I multi-select files, each file opens in a new instance of my
appication.
Correct, as it should be.
Quote
I tried limiting my instances using CreateMutex but it limits me to
opening one file only. How do I prevent my application from
multi-executing on multi-selecting files and instead point the
additional files to the already opened instance of my application?
You don't prevent it. Each new instance has to find the previous instance
and if found then send the new filename over to it via some kind of IPC
mechanism. Whether that be via window messages, pipes, sockets, COM,
whatever, that it your own choice. WM_COPYDATA usually works pretty well
for that. For example:
// this is needed because the VCL also uses WM_COPYDATA
// internally, so you don't want your code to mishandle the VCL's
// messages and vice versa...
#define MY_MAGIC_NUMBER (some unique number here)
class TMainForm : public TForm
{
__published:
void __fastcall FormShow(TObject *Sender);
private:
MESSAGE void __fastcall WMCopyData(TMessage &Message);
void __fastcall LoadFile(const AnsiString &FileName);
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
END_MESSAGE_MAP(TForm)
};
void __fastcall TMainForm::FormShow(TObject *Sender)
{
if( ParamCount()>0 )
LoadFile(ParamStr(1));
}
void __fastcall TMainForm::WMCopyData(TMessage &Message)
{
PCOPYDATASTRUCT pcds =
reinterpret_cast<PCOPYDATASTRUCT>(Message.LParam);
if( pcds->dwData == MY_MAGIC_NUMBER )
{
AnsiString FileName(static_cast<char*>(pcds->lpData),
pcds->cbData);
LoadFile(FileName);
}
else
TForm::Dispatch(&Message);
}
void __fastcall TMainForm::LoadFile(const AnsiString &FileName)
{
if( FileExists(FileName) )
{
TTabSheet *sheet = new TTabSheet(PageControl1);
sheet->PageControl = PageControl1;
sheet->Caption = ExtractFileName(FileName);
sheet->Hint = FileName;
TPlusGutter *gutter = new TPlusGutter(sheet);
gutter->Parent = sheet;
gutter->Align = alLeft;
gutter->ParagraphNumbers = true;
gutter->Visible = iLineNumbers;
gutter->LineNumbers = iLineNumbers;
gutter->Font->Color = cl3DDkShadow;
TPlusMemo *memo = new TPlusMemo(sheet);
memo->Parent = sheet;
memo->Align = alClient;
memo->Lines->LoadFromFile(FileName);
memo->Modified = false;
memo->Tag = 1;
}
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = CreateMutex(NULL, TRUE, "MyMutexNameHere");
if( hMutex == NULL )
return 0;
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
if( ParamCount()>0 )
{
HWND hWnd = FindWindow("TMainForm", "MyWindowCaptionHere");
if( hWnd != NULL )
{
AnsiString FileName = ParamStr(1);
COPYDATASTRUCT cds = {0};
cds.dwData = MY_MAGIC_NUMBER;
cds.cbData = FileName.Length();
cds.lpData = FileName.c_str();
SendMessage(hWnd, WM_COPYDATA, 0,
reinterpret_cast<LPARAM>(&cds));
}
}
}
else
{
// normal app startup stuff here...
}
CloseHandle(hMutex);
return 0;
}
Gambit
 

Re:ParamStr() and CreateMutex problem

Thanks Remy,
Roger.
On Wed, 1 Sep 2004 10:15:39 -0700, Remy Lebeau (TeamB)
< XXXX@XXXXX.COM >wrote:
Quote

"Roger Remacle" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

 

{smallsort}

Re:ParamStr() and CreateMutex problem

Remy,
I am still having problems with opening multiple files...
The below code allows multiple files to open only if associated with the
selected file extension and using popup 'open' in Explorer. If
multi-selecting and trying to 'Open With...'only the first file
displays... What am I missing?
#include "open00.cpp"
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HANDLE hMutex = CreateMutex(NULL, TRUE, "MyMutexNameHere");
if( hMutex == NULL )
return 0;
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
if( ParamCount()>0 )
{
HWND hWnd = FindWindow("TMainForm", "MainForm");
if( hWnd != NULL )
{
AnsiString FileName = ParamStr(1);
COPYDATASTRUCT cds = {0};
cds.dwData = MY_MAGIC_NUMBER;
cds.cbData = FileName.Length();
cds.lpData = FileName.c_str();
SendMessage(hWnd, WM_COPYDATA, 0,
reinterpret_cast<LPARAM>(&cds));
}
}
}
else
{
Application->Initialize();
Application->CreateForm(__classid(TMainForm), &MainForm);
Application->Run();
}
CloseHandle(hMutex);
return 0;
}
void __fastcall TMainForm::WMCopyData(TMessage &Message)
{
PCOPYDATASTRUCT pcds
=reinterpret_cast<PCOPYDATASTRUCT>(Message.LParam);
if( pcds->dwData == MY_MAGIC_NUMBER )
{
AnsiString
FileName(static_cast<char*>(pcds->lpData),pcds->cbData);
LoadFile(FileName);
}
else
TForm::Dispatch(&Message);
}
void __fastcall TMainForm::LoadFile(const AnsiString &FileName)
{
if( FileExists(FileName) )
{
TTabSheet *sheet = new TTabSheet(PageControl1);
sheet->PageControl = PageControl1;
sheet->Caption = ExtractFileName(FileName);
sheet->Hint = FileName;
TPlusGutter *gutter = new TPlusGutter(sheet);
gutter->Parent = sheet;
gutter->Align = alLeft;
gutter->ParagraphNumbers = true;
gutter->Font->Color = cl3DDkShadow;
TPlusMemo *memo = new TPlusMemo(sheet);
memo->Parent = sheet;
memo->Align = alClient;
memo->Lines->LoadFromFile(FileName);
memo->Modified = false;
memo->Tag = 1;
}
}
#define MY_MAGIC_NUMBER (345345)
class TMainForm : public TForm
{
__published: // IDE-managed Components
TPageControl *PageControl1;
void __fastcall FormShow(TObject *Sender);
private: // User declarations
MESSAGE void __fastcall WMCopyData(TMessage &Message);
void __fastcall LoadFile(const AnsiString &FileName);
public: // User declarations
__fastcall TMainForm(TComponent* Owner);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
END_MESSAGE_MAP(TForm)
};
Roger