Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 13
Пангин Дмитрий Викторович прислал письмо следующего содержания:
При программировании MDI-приложений возникает следующая задача: Если пользователь кликнул на файле, тип которого поддерживается создаваемым приложением, то, если приложение уже запущено, не нужно запускать новую копию приложения, а нужно открыть выбранный файл в уже работающем приложении. Я сделал это так (возможно есть более красивое решение):
>\\ В файле проекта:
>var
> i: integer;
> hMainForm:hwnd;
> copyDataStruct:TCopyDataStruct;
> ParamString:string;
> WParam,LParam:integer;
>begin
> \\ ищем главное окно приложения, вместо Caption - nil,
> \\ поскольку к заголовку главного окна может добавиться заголовок MDIChild
> \\ (нужно позаботиться об уникальности имени класса главной формы)
> hMainForm:= FindWindow('TMainForm', nil);
> if hMainForm = 0 then begin
>Application.Initialize;
> Application.CreateForm(TFrmMain, frmMain);
> for i:=1 to ParamCount do TMainForm(Application.MainForm).OpenFile(ParamStr(i));
> Application.Run;
> end
> else begin
>ParamString:='';
> for i:=1 to ParamCount do begin
> \\ запихиваем все параметры в одну строку с разделителями ?13
> ParamString:=ParamString+ParamStr(i)+ #13;
> end;
> \\ создаем запись типа TCopyDataStruct
> CopyDataStruct.lpData:=PChar(ParamString);
> CopyDataStruct.cbData:=Length(ParamString);
> CopyDataStruct.dwData:=0;
> WParam:=Application.Handle;
> LParam:=Integer(@CopyDataStruct);
> \\ отсылаем сообщение WM_COPYDATA главному окну открытого приложения
> SendMessage(hMainForm,WM_CopyData,WParam,LParam);
> Application.Terminate;
> end;
>end.
>\\ Обработчик сообщения WM_COPYDATA
>procedure TMainForm.CopyData(var Msg: TWMCopyData);
>var
> ParamStr:string;
> CopyDataStructure:TCopyDataStruct;
> i:integer;
> len:integer;
>begin
> CopyDataStructure:= Msg.CopyDataStruct^;
> ParamStr:='';
> len:= CopyDataStructure.cbData;
> for i:=0 to len-1 do begin
>ParamStr:=ParamStr+(PChar(CopyDataStructure.lpData)+i)^;
> end;
> i:=0;
> while not(Length(ParamStr)=0) do begin
> if isDelimiter(#13,ParamStr,i) then begin
>OpenFile(Copy(ParamStr,0,i-1));
> ParamStr:=Copy(ParamStr,i+1,Length(ParamStr)-i-1);
> end;
> inc(i);
> end;
> inherited;
>end;
Убиваем активное приложение
The_Sprite прислал письмо следующего содержания:
Данная функция позволяет завершить выполнение любой активной программы по её classname или заголовку окна.
Совместимость: Все версии Delphi
Исходный код функции
>procedure KillProgram(Classname : string; WindowTitle : string);
>const
> PROCESS_TERMINATE = $0001;
>var
> ProcessHandle : THandle;
> ProcessID: Integer;
> TheWindow : HWND;
>begin
> TheWindow := FindWindow(Classname, WindowTitle);
> GetWindowThreadProcessID(TheWindow, @ProcessID);
> ProcessHandle := OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId);
> TerminateProcess(ProcessHandle, 4);
>end;
Xianguang Li=(22 Октября 2000) В Delphi 5, при компиляции получается следующая ошибка:
>Incompatible types: 'String' and 'PChar'.
После изменения выражения
>TheWindow := FindWindow(ClassName, WindowTitle)
на
>TheWindow := FindWindow(PChar(ClassName), PChar(WindowTitle))
Нормально откомпилировалось.
И ещё: если мы не знаем ClassName или WindowTitle программы, которую мы хотим убить, то мы не сможем её завершить. Причина в том, что нельзя вызвать функцию в виде:
>KillProgram(nil, WindowTitle)
или
>KillProgram(ClassName, nil)
Компилятор не позволяет передать nil в переменную типа String.
Итак, я изменил объявление
>KillProgram(ClassName: string; WindowTitle: string)
на
>KillProgram(ClassName: PChar; WindowTitle: PChar),
вот теперь функция действительно может завершить любое приложение, если вы не знаете ClassName или WindowTitle этого приложения.
Pascal
Объекты
Проблема циклических ссылок
У меня имеется объект A и объект B, и им обоим нужно вызывать методы друг друга…
Объявите абстрактный базовый класс, определяющий интерфейс класса для того, чтобы другие классы могли его видеть. Используйте виртуальные абстрактные методы и свойства. Затем объявите другие классы подклассами базового класса (при необходимости). Данный метод существенно поможет в структурировании вашего приложения.
Mike Scott.
Создание множества экземпляров