2010-05-09 3 views
1

Я хочу написать текстовый редактор и назначить ему файлы txt. Моя проблема в том, что я хочу запустить только один экземпляр и открыть новый файл, чтобы отправить имя файла в первое уже запущенное приложение ... (Я хочу сделать это с помощью мьютекса). Вот небольшой тестоткрытые текстовые файлы в одном приложении

DPR выглядит следующим образом

uses 
    Windows, Messages, SysUtils, 
    Forms, 
    wndMain in 'wndMain.pas' {frmMain}; 

{$R *.res} 

var 
    PrevWindow : HWND; 
    S : string; 
    CData : TCopyDataStruct; 
begin 
    PrevWindow := 0; 
    if OpenMutex(MUTEX_ALL_ACCESS, False, 'MyMutex') <> 0 then 
    begin 
    repeat 
    PrevWindow:=FindWindow('TfrmMain', nil); 
    until PrevWindow<>Application.Handle; 

    if IsWindow(PrevWindow) then 
    begin 
     SendMessage(PrevWindow, WM_SYSCOMMAND, SC_RESTORE, 0); 
     BringWindowToTop(PrevWindow); 
     SetForegroundWindow(PrevWindow); 

     if FileExists(ParamStr(1)) then 
     begin 
      S:=ParamStr(1); 
      CData.dwData:=0; 
      CData.lpData:=PChar(S); 
      CData.cbData:=1+Length(S); 

      SendMessage(PrevWindow, WM_COPYDATA, 0, DWORD(@CData)); 
      end; 
     end; 
    end 
    else 
     CreateMutex(nil, False, 'MyMutex'); 

    Application.Initialize; 
    Application.CreateForm(TfrmMain, frmMain); 
    Application.Run; 
end. 

PAS:

type TfrmMain = class(TForm) 
    memo: TMemo; 
    private 
     procedure WMCopyData (var msg : TWMCopyData) ; message WM_COPYDATA; 
    public 
    procedure OpenFile(f : String); 
end; 

var 
    frmMain: TfrmMain; 

implementation 

{$R *.dfm} 

procedure TfrmMain.WMCopyData (var msg : TWMCopyData) ; 
var 
    f : String; 
begin 
    f:=PChar(msg.CopyDataStruct.lpData); 
    //ShowMessage(f); 
    OpenFile(f); 
end; 

procedure TfrmMain.OpenFile(f : String); 
begin 
    memo.Clear; 
    memo.Lines.LoadFromFile(f); 
    Caption:=f; 
end; 

этот код должен быть хорошо, но если я хочу, чтобы открыть текстовый файл (из второго приложения) , первое приложение получает сообщение, как это:

alt text http://img218.imageshack.us/img218/2175/errorjd.jpg

ТНА nks

+2

Этот код мьютекса неправильный. Всегда используйте 'CreateMutex', а не' OpenMutex'. Кроме того, цикл 'FindWindow' бессмыслен. Эта функция вернет только дескриптор окна текущего приложения, если заголовок вашего приложения был «TfrmMain», но почему вы когда-либо называли свое приложение? Кроме того, если 'FindWindow' * делает * возвращает дескриптор окна вашего приложения, повторные вызовы не дают другого ответа, так что цикл будет выполняться ровно один раз или он будет работать вечно. –

ответ

0

Я подозреваю, что вы используете Delphi 2009 или Delphi 2010. Этого использование версии строк Unicode, поэтому функция Length говорит количество символов в строке, но не число байт . Сообщение wm_CopyData должно знать количество отправленных байтов. Умножьте количество символов на два, или SizeOf(WideChar).

CData.lpData := PWideChar(S); 
CData.cbData := (1+Length(S)) * SizeOf(WideChar); 
+0

Это будет работать до тех пор, пока вы не будете пытаться повторно использовать код в версии, отличной от юникода. Если вы это сделаете, это будет нарушено. Лучше использовать 'PChar' и' sizeof (char) ', и пусть компилятор позаботится об интерпретации. –

+0

Я бы предпочел сделать это явным в этом случае, потому что мы имеем дело с межпроцессным обменом. Обе стороны должны согласиться относительно размера и формата полезной нагрузки. Если одна сторона скомпилирована в режиме Unicode, а другая - нет, мой код не будет компилироваться, намекая, что что-то не так, тогда как код, который использует PChar, будет скомпилировать find с обеих сторон, но связь не удастся во время выполнения. –

1

Это похоже на проблему Unicode. Вероятно, вы находитесь в D2009 или D2010. Вы должны указать размер в байтах, а не в хаарах. Попробуйте умножить свой length звонок на sizeof(char), и он должен работать.

+0

+1: Это, вероятно, будет самой распространенной ошибкой разработчиков Delphi на долгие годы. Вместо «SizeOf (Char)», я бы предложил использовать «StringElementSize (StringVariable)». –

Смежные вопросы