www.adept7.kiev.ua
| Форум| Гостевая| Ссылки| Программы| Исходные тексты| Наши партнеры|
   
| Главная| Рассылки| Услуги| Библиотека| Новости| Авторам| Программистам| Студентам|
delphi c++ assembler
 
Выборочный FAQ по некоторым интересным вопросам

Как мне получить путь к запущенной программе из нее самой?
Как в Delphi определить, где установлена Windows?
Как создать файлы с уникальными именами?
Как увеличить в RichEdit размер редактируемого файла?
Если приложение долго выполняет какой-то цикл, как сделать так, чтобы остальные приложения не подвисали?
Как выключить Ctrl+Alt+Del и/или Alt+Tab
Как перекодировать строки из Win(1251) кодовой страницы в Dos(866) кодовую страницу и обратно?
Как использовать анимированные курсоры в программе?
Как программно создать ярлык?
Как лучше сделать, если необходимо запустить внешний процесс и подождать, пока он отработает?
Как правильно создавать компоненты в run-time?
Как в TTreeView построить дерево открытых окон
Как использовать Clipboard для переноса данных в собственном формате?
Как перевести визуальный компонент, такой, как TPanel, в состояние       //перемещения(взять и перенести)?
Как изменить внешний вид хинтов (всплывающих подсказок)?
Переключение языка из программы на Delphi
Как проверить диск на наличие *.dbf в директории программы и соответствия полей?
Каким образом или какой функцией установить системную дату и время Windows 95 средствами Delphi.
Как определить нормальное (ненормальное) завершение выполнения файла. Как закрыть пустое окно, после выполнения.
Как определить работает ли уже данное приложение или это первая его копия?
Запуск внешней программы и ожидание ее завершения
gGI-програма должна выдавать в браузер Gif изображение.
 
 














Как мне получить путь к запущенной программе из нее самой?
Application.EXEName

Назад к содержанию


Как в Delphi определить, где установлена Windows?
GetWindowsDirectory
Пример:
  var  Windir  : String;
         WindirP : PChar;
  
                       .  .  .  .  .
         WinDirP := StrAlloc(MAX_PATH);
  
         Res := GetWindowsDirectory(WinDirP, MAX_PATH);
  
         if Res > 0 then WinDir := StrPas(WinDirP);
  
                     .  .  .  .  .
Назад к содержанию

Как создать файлы с уникальными именами?
Здесь удобнее всего использовать имя, состоящее из даты и времени, напри- мер: 2310566160798 для 23:10:56 16-07-98. Если перевести это число в 32-чную систему счисления, получим искомые восемь символов имени файла. Это хорошо использовать, если программа создает много файлов, которые потом будут ис- пользоваться. Если же нужно создать несколько временных файлов, то лучше воспользоваться фyнкцией GetTempFileName.

Назад к содержанию


Как увеличить в RichEdit размер редактируемого файла?
RichEdit1.Perform(EM_LIMITTEXT, нужный размер , 0);
Перед каждым открытием файла это действие необходимо повторять.

Назад к содержанию


Если приложение долго выполняет какой-то цикл, как сделать так, чтобы остальные приложения не подвисали?
1. Вставить в тело цикла: Application.ProcessMessages
2. Запустить этот цикл как отдельный процесс, используя класс TThread.
Назад к содержанию

Как перекодировать строки из Win(1251) кодовой страницы в Dos(866) кодовую страницу и обратно?
CharToOEM/OEMToChar и CharToOEMBuff/OEMToCharBuff.

Назад к содержанию


Как использовать анимированные курсоры в программе?
  Пример формы, использующей анимированный курсор:
      ........................................................
      procedure TForm1.Button1Click(Sender: TObject);
      var
        h : THandle;
      begin
        h := LoadImage(0,'C:\TheWall\Magic.ani',
          IMAGE_CURSOR, 0, 0,
          LR_DEFAULTSIZE or LR_LOADFROMFILE);
        if h = 0 then ShowMessage('Cursor not loaded')
        else
        begin
          Screen.Cursors[1] := h;
          Form1.Cursor := 1;
        end;
      end;
    ... ..... ...... ....... ....... ...... ..
Назад к содержанию

Есть программа на Delphi, котоpая отображает какой-то html. В html используется gif-файл. Как в Delphi-пpоекте указать, чтобы этот gif находился в exe как некий кусок кода. А когда надо будет, записать его обратно в gif-файл без изменений, выковырнув из exe?

    Можно, используя RxLib. После его установки в меню View появится пунктик Project Resources. Hужно выбрать Project Resources->New->User Data и добавить нужный файл. В данном случае ресурс был назван "RCDATA_1".
Если RxLib нет, то нужно создать файл описания ресурсов:

=== Begin gifs.rc ===
  mygif rcdata "имя_gif-файла.gif"
  mygif1 rcdata "RCDATA_1"
=== End dots.rc ===
Потом скомпилировать его командой brcc32 gifs.rc и получить gifs.res В начало модуля добавь строчку {$R gifs.res}
В своей программе необходимо написать:
var
    rs     : TResourceStream;
    a      : Pointer;
  begin
    rs:=TResourceStream.Create(hinstance,'RCDATA_1',RT_RCDATA);
    try
      GetMem(a,rs.size);
      rs.Read(a^,rs.size);  {Теперь a - динамический указатель на код}
  
      { Здесь делается все, что необходимо с кодом, используя указатель a }
  
      FreeMem(a);
    finally
      rs.Free;
    end;
  end;
  
  А можно и так, если необходимо записать ресурс в файл:
  var
    rs     : TResourceStream;
    fs     : TFileStream;
  begin
     rs:=TResourceStream.Create(hInstance, 'mygif', RT_RCDATA);
     fs:=TFileStream.Create('имя_gif-файла.gif', fmCreate);
     try
       fs.CopyFrom(rs, rs.Size);
     finally
       fs.Free;
       rs.Free;
     end;
end;
Назад к содержанию

Как программно создать ярлык?
  ........................................................
    uses ShlObj, ComObj, ActiveX;
  
    procedure CreateLink(const PathObj, PathLink, Desc, Param: string);
    var
      IObject: IUnknown;
      SLink: IShellLink;
      PFile: IPersistFile;
    begin
      IObject := CreateComObject(CLSID_ShellLink);
      SLink := IObject as IShellLink;
      PFile := IObject as IPersistFile;
      with SLink do begin
        SetArguments(PChar(Param));
        SetDescription(PChar(Desc));
        SetPath(PChar(PathObj));
      end;
      PFile.Save(PWChar(WideString(PathLink)), FALSE);
    end;
  ........................................................
Назад к содержанию

Как лучше сделать, если необходимо запустить внешний процесс и подождать, пока он отработает?
procedure TForm1.Button1Click(Sender: TObject);
var si:STARTUPINFO;
    pi:PROCESS_INFORMATION;
    cmdline:string;
begin
    ZeroMemory(@si,sizeof(si));
    si.cb:=SizeOf(si);
    cmdline:='c:\command.com';
    if not CreateProcess( nil, // No module name (use command line).
        PChar(cmdline),  // Command line.
        nil,             // Process handle not inheritable.
        nil,             // Thread handle not inheritable.
        False,           // Set handle inheritance to FALSE.
        0,               // No creation flags.
        nil,             // Use parent's environment block.
        nil,             // Use parent's starting directory.
        si,              // Pointer to STARTUPINFO structure.
        pi )             // Pointer to PROCESS_INFORMATION structure.
       then
        begin
         ShowMessage( 'CreateProcess failed.' );
         Exit;
        end;
    WaitForSingleObject( pi.hProcess, INFINITE );
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
    ShowMessage('Done !');
end;

Назад к содержанию


Как правильно создавать компоненты в run-time?
Давайте создадим.
Сущность свойства Owner в том, что перед уничтожением владельца, он уничтожает (через Free) принадлежащие ему объекты. Таким образом, все зависит от того, кому Вы хотите доверить уничтожение созданных форм/компонентов. В частности, если Вы сами будете этим заниматься, то AOwner может быть, например, nil.
Для того, чтобы созданный компонент появился на экране, надо указать его родителя, заполнив свойство Parent, например:
NewButton.Parent := Form1;
Пример кода, обрабатывающего события от свежесозданных компонентов:
type
TForm1 = class(TForm)
{ ... }
private
{ эта процедура будет вызываться при нажатии на кнопку }
procedure ButtonClicked(Sender : TObject);
public
{ в этой процедуре происходит создание кнопки }
procedure CreateButton;
end;
{ ... }
procedure TForm1.CreateButton;
var
Btn : TButton;
begin
Btn := TButton.Create(Self); { Уничтожать кнопку будет форма }
Btn.Parent := Self; { Родителем кнопки будет форма }
Btn.OnClick := ButtonClicked; { Процедура, которая будет исполняться при }
Btn.Visible := true; { нажатии на кнопку }
end;

Назад к содержанию


Как в TTreeView построить дерево открытых окон?
Alex Shakhajlo 1
Alex.Shakhajlo@f701.n461.z2.fidonet.org
Мне стало интересно построить дерево окон и вот что у меня получилось:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, HistEdit, Buttons, StdCtrls, ColoredGrid, TLHelp32, ComCtrls;
type
TForm1 = class(TForm)
List : TTreeView;
procedure FormCreate(Sender : TObject);
private
{ Private declarations }
procedure listlevel(N : TTreeNode; H : HWND);
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.ListLevel;
var
B : array[0..128] of char;
S : String;
T : TTreeNode;
C, W : HWND;
begin
W := H;
while W <> 0 do
begin
GetClassName (W, @B, 128);
S := StrPas(B);
GetWindowText(W, @B, 128);
S := S + '(' + StrPas(B) + ')';
T := List.Items.AddChild(N, S);
C := GetWindow(W, GW_CHILD);
ListLevel(T, C);
W := GetNextWindow(W, GW_HWNDNEXT);
end;
end;
procedure TForm1.FormCreate(Sender : TObject);
var
H : HWnd;
begin
H := GetDeskTopWindow;
ListLevel(nil, H);
end;

end.
Назад к содержанию

     Как использовать Clipboard для переноса данных в собственном формате?
Не только возможно, именно так поступают функции Clipboard.GetComponent и Clipboard.SetComponent.
Сперва Вы должны зарегистрировать свой собственный формат данных для Clipboard с помощью функции RegisterClipboardFormat():

CF_MYFORMAT := RegisterClipboardFormat('My Format Description');
Далее вы должны выполнить эти шаги : 1. Создать поток (memory stream) и записать туда данные.
2. Создать глобальный буфер в памяти и скопировать поток туда.
3. Вызвать Clipboard.SetAsHandle(), чтобы поместить буфер в clipboard.
Пример:
var
HBuf : THandle;
BufPtr : Pointer;
MStream : TMemoryStream;
begin
MStream := TMemoryStream.Create;
try
{-- Write your data to the stream. --}
HBuf := GlobalAlloc(GMEM_MOVEABLE, MStream.Size);
try
BufPtr := GlobalLock(HBuf);
try
Move(MStream.Memory^, BufPtr^, MStream.Size);
Clipboard.SetAsHandle(CF_MYFORMAT, HBuf);
finally
GlobalUnlock(HBuf);
end;
except
GlobalFree(HBuf);
raise;
end;
finally
MStream.Free;
end;
end;
ВНИМАНИЕ: Не уничтожайте буфер, созданный с GlobalAlloc(). Поскольку Вы поместили его в Clipboard, это уже дело Clipboard'а его уничтожить. Опять же, получая буфер из Clipboard, не уничтожайте этот буфер - просто сделайте копию содержимого.
Для обратного получения потока и данных, сделайте что-нибудь вроде этого:
var
HBuf : THandle;
BufPtr : Pointer;
MStream : TMemoryStream;
begin
HBuf := Clipboard.GetAsHandle(CF_MYFORMAT);
if HBuf <> 0 then
begin
BufPtr := GlobalLock(HBuf);
if BufPtr <> nil then
begin
try
MStream := TMemoryStream.Create;
try
MStream.WriteBuffer(BufPtr^, GlobalSize(HBuf));
MStream.Position := 0;
{-- Read your data from the stream. --}
finally
MStream.Free;
end;
finally
GlobalUnlock(HBuf);
end;
end;
end;
end;
Назад к содержанию

Как перевести визуальный компонент, такой, как TPanel, в состояние перемещения (взять и перенести)?
Borland TI N2909 (перевод: Акжан Абдулин)
 

Пример:

{ В случае Panel1 : TPanel - обработчик события OnMouseDown }

procedure TForm1.Panel1MouseDown(Sender : TObject; Button : TMouseButton;
Shift : TShiftState; X, Y : Integer);
const
SC_DRAGMOVE = $F012; { a magic number }
begin
ReleaseCapture;
P.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
Назад к содержанию

     Как изменить внешний вид хинтов (всплывающих подсказок)?
Dmitry Medved
 

1. Создаем свой класс - потомок от THintWindow

type
TCustomHint = class(THintWindow)
public
constructor Create(AOwner: TComponent); override;
end;
Пpимечание
  • Этот способ не позволит изменить цвет шpифта - для этого пpидется пеpекpывать метод Paint;
  • Если пеpекpыть CreateParams, то можно, напpимеp, наpисовать Hint в фоpме облачка.

  • 2. Меняем фонт:
    constructor TCustomHint.Create(AOwner : TComponent);
    begin
    inherited Create(AOwner);
    with Canvas.Font do // Именно так, а не пpосто Font!
    begin
    Name := 'Times New Roman Cyr';
    Style := [fsBold, fsItalic];
    Size := 40;
    end;
    end;
    3. Устанавливаем новый хинт
    procedure TForm1.FormCreate(Sender : TObject); // Это может быть любой обpаботчик
    begin
    HintWindowClass := TMyHint; // Устанавливаем глобальную пеpеменную
    Application.ShowHint := False; // Application.FHintWindow.Free
    Application.ShowHint := True; // Application.FHintWindow.Create
    end;
    Назад к содержанию

    Переключение языка из программы
    Для переключения языка применяется вызов LoadKeyboardLayout:
    var russian, latin: HKL; 
         russian:=LoadKeyboardLayout('00000419', 0);
         latin:=LoadKeyboardLayout('00000409', 0);
        
        -- -- -- -- -- где то в  программе --- --- --- 
       SetActiveKeyboardLayout(russian);

    Отключение CTRL-ALT-DEL

    при помощи SystemParametersInfo
    Бывают ситуации, когда вашей программе понадобится отключить реакцию на клавиши
    Ctrl-Alt-Del (например, если вы не хотите, чтобы ее выгрузили из памяти). Это
    можно сделать при помощи функции API SystemParametersInfo, которая позволяет
    узнать, либо установить параметры операционной системы, такие как установки
    клавиатуры, дисплея, звука и т.д. Она используется в Панели Управления. Синтакс
    функции следующий:
    BOOL SystemParametersInfo(
    UINT uiAction,  // параметр, который нужно узнать или установить
    UINT uiParam,   // зависит от действия
    PVOID pvParam,  // зависит от действия
    UINT fWinIni    // флаг обновления информации о пользователе (user profile));
    Значение каждого параметра объясняется в Win32 Developer's Reference. Теперь,
    чтобы сделать то, что мы хотим, вызываем следующую прцедуру:
    procedure DisableCtrlAltDel;
     var
     i : integer;
    begin
     i := 0;
    SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @i, 0);
    end.
    Аналогично можно отключить Alt-Tab. Для этого нужно задать SPI_SETFASTTASKSWITCH
    в качестве первого параметра функции.
    Как проверить диск на наличие *.dbf в директории программы и соответствия полей?

    Ivanuts V.A. (ivanuts@altavista.net) 31.10.2001
    1. Для определения наличия любого файла на диске используется стандартное выражение:

    if not FileExists(FTableName) then
    raise EError.Create('Таблица ' + ExtractFileName(FTableName) + ' по указанному пути отсутствует.')
    2. Чтобы перед использованием DBF-таблицы проверить ее версию можно воспользоваться следующей функцией:
    const
    DB3 = $03; //Версия 3.х
    DB4 = $04; //Версия 4.х
    DB5 = $05; //Версия for Windows
    DB3Memo = $83; //Версия 3.х cполями MEMO
    DB4Memo = $84; //Версия 4.х cполями MEMO
    function TMyMenu.GetTableVersion : Byte;
    ....
    FFile := TFileStream.Create (FTableName, fmOpenReadWrite);
    try
    //Информация о заголовке таблицы
    FFile.Seek(0, soFrombeginning);
    FFile.ReadBuffer(FHeader, Sizeof(FHeader)); //FHeader - переменная, указывающая на структуру заголовка
    Result := FHeader.VersionNumber; //Здесь VersionNumber - поле из записи FHeader
    except
    Raise EError.Create('Ошибка чтения заголовка таблицы.');
    end;
    ....
    Дальше зная с какой именно таблицей приходится работать, нетрудно выбрать переменую, указывающую на структуру полей таблицы и т.д.
    Каким образом или какой функцией установить системную дату и время Windows 95 средствами Delphi.
    Ivanuts V.A. (ivanuts@altavista.net) 31.10.2001
    В своих приложениях, которые требуют установки единого времени и даты на разных машинах, я использую установку системного времени и даты , взятых путем запроса с сервера БД. У меня это работает вот так:
    procedure TGlavMenu.SetSysTime(Sender: TObject);
    var
    Present : TSystemTime;
    Year, Month, Day, Hour, Min, Sec, MSec: Word;
    begin
    qrTime.Open;{ Этот квери возвращает системное время и дату с сервера БД. Здесь можно использовать и другие источники - например TEdit и т.д.}
    DecodeDate(qrTimeDATE.Value, Year, Month, Day);
    DecodeTime(qrTimeDATE.Value, Hour, Min, Sec, MSec);
    Present.wYear := Year;
    Present.wMonth := Month;
    Yares := Year;
    Months := Month;
    Present.wDay := Day;
    Present.wHour := Hour - 3;
    Present.wMinute := Min;
    Present.wSecond := Sec;
    Present.wMilliseconds := MSec;
    SetSystemTime(Present);
    qrTime.Close;

    end;
     
    Как определить нормальное (ненормальное) завершение выполнения файла. Как закрыть пустое окно, после выполнения.

    Ivanuts V.A. (ivanuts@altavista.net) 31.10.2001
    Если речь идет о выполнении файла в паралельном процессе, то необходимо создать такой процесс:

    var
    Startup: TStartupInfo;
    Process: TProcessInformation;
    Status: DWORD;
    szApp, szCmdLine : String;
    Env: Pointer;
    begin
    Result := UM_ERROR;
    Startup.lpReserved := PChar(0);
    Startup.lpDesktop := PChar(0);
    Startup.lpTitle := PChar(0);
    Startup.dwFlags := STARTF_USESHOWWINDOW;
    Startup.wShowWindow := SW_HIDE;{Вот здесь и необходимо выбрать способ запуска - видимое или скрытое окно.}
    Startup.cbReserved2 := 0;
    Startup.lpReserved2 := PByte(0);
    if CreateProcess(
    PChar(szApp), // lpApplicationName
    PChar(szCmdLine), // lpCommandLine
    PSecurityAttributes(0), // lpProcessAttributes
    PSecurityAttributes(0), // lpThreadAttributes
    False, // bInheritHandles
    HIGH_PRIORITY_CLASS, // dwCreationFlags
    Env, // lpEnvironment
    PChar(0), // lpCurrentDirectory
    Startup, // lpStartupInfo
    Process // lpProcessInformation) then
    begin
    GetExitCodeProcess(Process.hProcess, Status);
    while Status = STILL_ACTIVE do
    begin
    Sleep(10);
    GetExitCodeProcess(Process.hProcess, Status);
    end;
    Result := Status;
    end;
    end;
    Результат такой функции и даст ответ о завершении процесса. Подробней о функциях CreateProcess и GetExitCodeProcessможно прочесть в Help for Delphi.
    Как определить работает ли уже данное приложение или это первая его копия?
    Alex Shakhajlo 2.11.2001
    Для Delphi 1. Каждый экземпляр программы имеет ссылку на свою предыдущую копию - hPrevInst: hWnd. Ее можно проверить перед созданием приложения и при необходимости отреагировать соответствующим образом. Если запущена только одна копия, то эта ссылка равна нулю.
    Пример:
    procedure TForm1.FormCreate(Sender: TObject); 
        begin 
          {Проверяем есть ли указатель на предыдущую копию приложения}
          IF hPrevInst <> 0 THEN BEGIN 
            {Если есть, то выдаем сообщение и выходим}
            MessageDlg('Программа уже запущена!', mtError, [mbOk], 0); 
            Halt; 
          END; 
          {Иначе - ничего не делаем (не мешаем созданию формы)}
      end;
    P.S. Для выхода необходимо использовать Halt, а не Close, как хотелось бы, так как форма еще не создана и закрывать нечего.
    Есть и другой способ - по списку загруженных приложений
    procedure TForm1.FormCreate(Sender: TObject);
        VAR
         Wnd : hWnd;
         buff : ARRAY[0.. 127] OF Char;
        Begin
         Wnd := GetWindow(Handle, gw_HWndFirst);
         WHILE Wnd <> 0 DO BEGIN
          IF (Wnd <> Application.Handle) AND (GetWindow(Wnd, gw_Owner) = 0)
          THEN BEGIN
           GetWindowText (Wnd, buff, sizeof (buff ));
           IF StrPas (buff) = Application.Title THEN 
           BEGIN
            MessageDlg('Приложение уже загружено', mtWarning, [mbOk], 0);
            Halt;
           END;
          END;
          Wnd := GetWindow (Wnd, gw_hWndNext);
         END;
      End;
    Еще один интересный способ для Win32. Дело в том, что можно в памяти создавать временные файлы. При перезагрузке они теряются, а так существуют. Кстати, этот метод можно использовать и для обмена информацией между вашими приложениями.
    Пример:
    program Project1;
        uses
          Windows, // Обязательно
          Forms,
          Unit1 in 'Unit1.pas' {Form1};
        {$R *.RES}
        Const
         MemFileSize = 1024;
         MemFileName = 'one_inst_demo_memfile';
        Var
         MemHnd : HWND;
        begin
          { Попытаемся создать файл в памяти }
          MemHnd := CreateFileMapping(HWND($FFFFFFFF),
                                      nil,
                                      PAGE_READWRITE,
                                      0,
                                      MemFileSize,
                                      MemFileName);
          { Если файл не существовал запускаем приложение }
          if GetLastError<>ERROR_ALREADY_EXISTS then
          begin
           Application.Initialize;
           Application.CreateForm(TForm1, Form1);
           Application.Run;
          end;
          CloseHandle(MemHnd);
      end.
    Часто при работе у пользователя может быть открыто 5-20 окон и сообщение о том, что программа уже запущено приводит к тому, что он вынужден полчаса искать ранее запущенную копию. Выход из положения - найдя копию программы активировать ее, для чего в последнем примере перед HALT необходимо добавить строку :
    SetForegroundWindow(Wnd);
    Например так:
    program Project0;
    uses
      Windows,  // !!!
      Forms,
      Unit0 in 'Unit0.pas' {Form1};
    var
      Handle1 : LongInt;
      Handle2 : LongInt;
    {$R *.RES}
    begin
      Application.Initialize;
      Handle1 := FindWindow('TForm1',nil);
      if handle1 = 0 then
        begin
          Application.CreateForm(TForm1, Form1);
          Application.Run;
        end
      else
        begin
          Handle2 := GetWindow(Handle1,GW_OWNER);
           //Чтоб заметили :)
          ShowWindow(Handle2,SW_HIDE); ShowWindow(Handle2,SW_RESTORE);
          SetForegroundWindow(Handle1); // Активизируем
        end;
    end.

    Запуск внешней программы и ожидание ее завершения


    procedure TForm1.Button1Click(Sender: TObject);
        var
          si : Tstartupinfo;
          p  : Tprocessinformation;
        begin
         FillChar( Si, SizeOf( Si ) , 0 );
         with Si do begin
          cb := SizeOf( Si);
          dwFlags := startf_UseShowWindow;
          wShowWindow := 4;
         end;
         Application.Minimize;
         Createprocess(nil,'notepad.exe',nil,nil,false,Create_default_error_mode,nil,nil,si,p);
         Waitforsingleobject(p.hProcess,infinite);
         Application.Restore;
      end;

    СGI программа должна показывать GIF изображение.

    Имею тег Программа должна выдавать в браузер изображение. Прочитать JPeg, указать ContentType=Image/jpeg и выдать изображение в SaveToStream умею. Как сделать тоже самое для файлов GIF, в особенности анимационных? Если можно просто перелить дисковый файл (пусть он хоть трижды GIF) в Response CGI-програмы, то как это сделать?
     

    Выдайте из скрипта следующее:

    Content-type: image/gif

    <содержимое gif-файла>


    Как программно создать ярлык?

    uses ShlObj, ComObj, ActiveX;
        
        procedure CreateLink(const PathObj, PathLink, Desc, Param: string);
        var
          IObject: IUnknown;
          SLink: IShellLink;
          PFile: IPersistFile;
        begin
          IObject := CreateComObject(CLSID_ShellLink);
          SLink := IObject as IShellLink;
          PFile := IObject as IPersistFile;
          with SLink do begin
            SetArguments(PChar(Param));
            SetDescription(PChar(Desc));
            SetPath(PChar(PathObj));
          end;
          PFile.Save(PWChar(WideString(PathLink)), FALSE);
      end;
     

     
     
     
     
     

    Используются технологии uCoz
    Используются технологии uCoz

    Rambler's Top100 Rambler's Top100
    Используются технологии uCoz

    Rambler's Top100 Rambler's Top100

    ©  Adept Design Studio

    Используются технологии uCoz