在一个应用程序中打开文本文件

时间:2010-05-09 19:38:45

标签: delphi mutex

我想编写一个文本编辑器并将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

感谢

2 个答案:

答案 0 :(得分:1)

这看起来像是一个Unicode问题。你可能在D2009或D2010。您需要以字节为单位给出大小,而不是以字符为单位。尝试将length调用乘以sizeof(char),它应该有效。

答案 1 :(得分:0)

我怀疑你正在使用Delphi 2009或Delphi 2010.那些版本使用Unicode字符串,因此Length函数告诉字符串中字符的数量,而不是数字< EM>字节。 wm_CopyData消息需要知道要发送的字节数。将字符数乘以2,或SizeOf(WideChar)

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