Перейти к содержанию
Fire Monkey от А до Я

Dmitry_4501

Пользователи
  • Постов

    69
  • Зарегистрирован

  • Посещение

  • Победитель дней

    9

Сообщения, опубликованные Dmitry_4501

  1. В 13.08.2023 в 09:44, Letter сказал:

    Спасибо еще раз! А не могли бы Вы подсказать как удалить записи?  То есть из текстового файла загружаю список. И нужно так же , какие отмечены чикетом, то те удалить записи. Пробовал ListBox1.Items.Delete(r);  Но не получается.

    Попробуйте вот так (не самый идеальный вариант, но он работает и ошибок не выдает).

    procedure TForm1.Button1Click(Sender: TObject);
      begin
        var selectedItems: TArray<TListBoxItem>; // Объявляем массив из объектов TListBoxItem
        for var item: TFMXObject in ListBox1.Children.Items[1].Children do // Перебираем каждый дочерний компонент в ListBox, который является экземпляром класса TListBoxItem.
          begin
            if item is TListBoxItem then // Проверяем, является ли item экземпляром класса TListBoxItem
              if TListBoxItem(item).IsChecked then // Проверяем, является ли элемент отмеченным галочкой
                begin
                  System.SetLength(selectedItems, System.Length(selectedItems) + 1); // Увеличиваем длину массива
                  selectedItems[High(selectedItems)] := TListBoxItem(item); // Вставляем элемент в массив
                end;
          end;
    
        DeleteAllCheckedFiles(selectedItems);
      end;
    
    procedure TForm1.DeleteAllCheckedFiles(items: TArray<TListBoxItem>);
      begin
        if System.Length(items) < 1 then Exit;
        for var i: Integer := 0 to System.Length(items) - 1 do
          begin
            var item: TListBoxItem := items[i];
            if Assigned(item) then
              begin
                // TFile.Delete(item.Text);
                item.Free(); // Освобождаем память, тем самым объект уничтожится и больше не будет находиться в списке элементов TListBox
              end;
          end;
      end;
  2. 13 часов назад, Aptyp сказал:

    @Dmitry_4501 в том то и дело, что не будет. Я прямо в моей функции WindowProc писал условие и рисовал. Причём обрабатывал не только WM_NCPAINT, но и WM_PAINT и многое другое, что хоть как-то может быть с этим связано. В FireMonkey это стабильно не работает. Иногда рисует, иногда нет. По крайней мере в моём случае, когда форма Acrylic и к ней применяется стиль.

        if uMsg = WM_NCPAINT then
          begin
          	...
          end;

     

    Можно увидеть вашу реализацию безрамочной формы и вашей WindowProc?

  3. 8 часов назад, Aptyp сказал:

    А теперь что касается изначального вопроса: к сожалению мне не удалось нормально рисовать на неклиентской части формы в FireMoneky. Поэтому я убираю клиентскую часть выставляя в стилях ширину боковых границ и высоту нижней границы и заголовка равные 0. То есть BorderStyle остаётся Sizeable, но границ просто не видно. Делаю свои кнопки формы (закрыть, развернуть...), похожие по стилю в Windows с обработчиками, что выше в сообщении, а изменение размеров окна беру из примера @Dmitry_4501, в итоге выходит такой код:

    type PWMNCHitTest = ^TWMNCHitTest;
    
    if uMsg = WM_NCHITTEST then
      begin
        const EdgeWidth = 6;
        var NCHitTest: PWMNCHitTest := PWMNCHitTest(lParam);
        var xPos := LOWORD(lParam);
        var yPos := HIWORD(lParam);
        var Pos: TPointF := Self.ScreenToClient(TPointF.Create(xPos, yPos));
    
        Result := 0;
        if Pos.X <= EdgeWidth then
          begin
            if Pos.Y <= EdgeWidth then
              Result := HTTOPLEFT
            else if Pos.Y >= Self.ClientHeight - EdgeWidth then
              Result := HTBOTTOMLEFT
            else
              Result := HTLEFT;
          end
        else if Pos.X >= Self.ClientWidth - EdgeWidth then
          begin
            if Pos.Y <= EdgeWidth then
              Result := HTTOPRIGHT
            else if Pos.Y >= Self.ClientHeight - EdgeWidth then
              Result := HTBOTTOMRIGHT
            else
              Result := HTRIGHT;
          end
        else if Pos.Y <= EdgeWidth then
          Result := HTTOP
        else if Pos.Y >= Self.ClientHeight - EdgeWidth then
          Result := HTBOTTOM;
    
        Prevent := Result <> 0;
      end;

    Ну и стоит учесть, что в Firemonkey так просто не обработаешь сообщения окна. Надо делать некий костыль для формы в виде кода:

    type
      TMainForm = class(TForm)
        private
          FOldWndProc: LONG_PTR;
        protected
          procedure CreateHandle; override;
          procedure DestroyHandle; override;
      end;
    
    ...
    
    procedure TMainForm.CreateHandle;
      function WindowProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
      var
        frm: TCommonCustomForm;
        Prevent: Boolean;
      begin
        frm := FMX.Platform.Win.FindWindow(hwnd);
        Assert(frm.InheritsFrom(TForm));
        Prevent := False;
    
        if uMsg = WM_NCHITTEST then
          begin
          	...
          end;
    
        if not Prevent then
          Result := CallWindowProc(Ptr(TForm(frm).FOldWndProc), hwnd, uMsg, WParam, lParam);
      end;
    begin
      inherited CreateHandle;
      FOldWndProc := GetWindowLongPtr(FormToHWND(Self), GWL_WNDPROC);
      SetWindowLongPtr(FormToHWND(Self), GWL_WNDPROC, NativeInt(@WindowProc));
    end;
    
    procedure TMainForm.DestroyHandle;
    begin
      Assert( FormToHWND(Self) <> 0 );
      SetWindowLongPtr(FormToHWND(Self), GWL_WNDPROC, FOldWndProc);
      inherited DestroyHandle;
    end;

    Конечно же всё это только для Windows платформы.

    Оконные сообщения в FMX можно обрабатывать так же как и в VCL.
    Достаточно в вашу WindowProc добавить это:

    var Message: TMessage; 
    
    Message.Msg := uMsg;
    Message.WParam := wParam;
    Message.LParam := lParam;
    Message.Result := 0;
    
    frm.Dispatch(Message);

    Тогда потом можно будет смело написать что-то вроде

    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT; 


    И оно будет работать.
     

  4. В 03.08.2023 в 02:41, Aptyp сказал:

    @Dmitry_4501 Спасибо, очень классный пример. Те пункты, которые не получились – это уже не столь важно.

    Но есть одна проблема, то ли я дурак, то ли лыжи не едут, но FireMonkey вообще никак не реагирует на следующие команды:
     

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_CLOSE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MINIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_RESTORE, 0);

    При этом команда перемещения отрабатывает штатно:

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, $F012, 0);

     

    P.S. Рекомендую Position всегда ставить poScreenCenter. Так как при poDesktopCenter и наличии нескольких мониторов форма появляется между экранами, а не в центе одного из них. Я это сам обнаружил только, когда подключил себе второй монитор.

     

    image.png

    Кажется я понял в чем причина.

    Попробуйте заменить SendMessage на PostMessage, у меня после этого окно развернулось на весь экран.

  5. 16 часов назад, Aptyp сказал:

    @Dmitry_4501 Спасибо, очень классный пример. Те пункты, которые не получились – это уже не столь важно.

    Но есть одна проблема, то ли я дурак, то ли лыжи не едут, но FireMonkey вообще никак не реагирует на следующие команды:
     

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_CLOSE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MINIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_RESTORE, 0);

    При этом команда перемещения отрабатывает штатно:

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, $F012, 0);

     

    P.S. Рекомендую Position всегда ставить poScreenCenter. Так как при poDesktopCenter и наличии нескольких мониторов форма появляется между экранами, а не в центе одного из них. Я это сам обнаружил только, когда подключил себе второй монитор.

     

    image.png

    Да. Окно на FireMonkey не реагирует на это сообщение. Странно, я точно помню что делал уже такое на FireMonkey и оно работало.
    Правда было это давно, попробую еще поковыряться, может получится.

  6. 16 часов назад, Aptyp сказал:

    @Dmitry_4501 Спасибо, очень классный пример. Те пункты, которые не получились – это уже не столь важно.

    Но есть одна проблема, то ли я дурак, то ли лыжи не едут, но FireMonkey вообще никак не реагирует на следующие команды:
     

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_CLOSE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MINIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
    
    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, SC_RESTORE, 0);

    При этом команда перемещения отрабатывает штатно:

    SendMessage(FormToHWND(Self), WM_SYSCOMMAND, $F012, 0);

     

    P.S. Рекомендую Position всегда ставить poScreenCenter. Так как при poDesktopCenter и наличии нескольких мониторов форма появляется между экранами, а не в центе одного из них. Я это сам обнаружил только, когда подключил себе второй монитор.

     

    image.png

    Хм, странно. Должно работать. Сейчас открою проект еще раз у себя. Гляну.

  7. В 01.08.2023 в 20:16, OnePeople сказал:

    изменять размер окна - легко реализуемо

    перемещение с привязкой к краям экрана, когда система предлагает развернуть экран на пол экрана или в угол поместить -

    это да, но никаких проблем с размещение любых компонентов и рисованием любых рисунков.

    Подключусь к теме...

    Как-то пытался сделать подобное и в принципе получилось, безрамочное окно, которое по-нативному работает, что удалось заставить работать:

    • Если взять окно за заголовок и начать двигать им туда-сюда, то все остальные окна свернутся - нативное поведение
    • Если взять окно за заголовок то в Windows 11 появляется верхнее меню с макетами отображения на экране - нативное поведение
    • Если взять окно за заголовок и перетащить его к одному из краев экрана, то появится макет для отображения окна - нативное поведение
    • Нативным образом реализовано изменение размера за все края формы, включая диагональные.
    • Так же окно имеет нативные анимации появления\исчезания, разворачивания\сворачивания
    • Так же имеется нативная тень
    • А на Windows 11 имеются закруглённые края окна


    Что не получилось:

    • Не получилось реализовать нативное поведение, когда в Windows 11 наводишь курсор на кнопку "развернуть окно", там появляется небольшое меню с макетами отображения на экране.
    • Нормально реализовать границы для изменения размеров окна, ибо из-коробки они находятся за пределами окна в поле где тень у окна (в Windows 10 и Windows 11 так), у меня же они внутри окна. Как-то делал и получалось, но уже не помню.

    Код несложно адаптировать и под FireMonkey

    BorderlessWindowWithAeroSnap.zip

  8. Проходишь циклом по всему списку и у каждого элемента проверяешь свойство IsChecked, если оно true, то тогда при помощи TFile.Delete удаляешь файл.

     

    Как-то так:

    procedure DeleteAllCheckedFiles();
    begin
      if ListBox1.Count < 1 then Exit; // Если количество элементов меньше 1, то выходим из процедуры
      for var I: Integer := 0 to ListBox1.Count - 1 do
        if ListBox1.ListItems[I].IsChecked then // Проверяем свойство IsChecked (т.е отмечен ли элемент)
          TFile.Delete(ListBox1.ListItems[I].Text); // Удаляем файл (только в том случае, если в тексте элемента записан путь до файла, иначе придется переделать эту строчку под свои нужды)
    end;

    Для TFile.Delete необходимо подключить юнит System.IOUtils

  9. Не проще ли использовать простой TImage?

    TImageControl тоже можно заставить работать с прозрачностью, для этого придется создать свой стиль для него при помощи Edit Custom Style c прозрачным фоном

  10. Это добавлено специально чтобы в дизайнере форм случайно не переместить компонент. Очень удобно, в VCL такого нет и порой это может вылиться в мороку, когда вместо одного компонента выбрал другой и перетащил, тем самым поломав весь UI.

  11. Если еще актуально, то есть TTextEditor, но он для VCL, можно попробовать переписать его для FMX, либо при помощи костылей прицепить VCL-форму с компонентом к FMX-форме.

     

    https://github.com/TextEditorPro/TTextEditor

  12. 1 час назад, Sascha сказал:

    Она заброшена автором. Для Delphi 10.4.1 ее можно установить?

    Почему нет? В случае возникновения ошибок всегда можно их исправить самостоятельно.

     

    1 час назад, Sascha сказал:

    на гитхабе нашел два продолжения проекта:

    https://github.com/ms301/fgx-firemonkey

    https://github.com/theilgaz/FGX

    Вы каким пользуетесь?

    Сейчас никаким. Поначалу было нужно, сейчас не использую FireMonkey почти нигде.

  13. Попробуйте библиотеку компонентов FGX, она содержит компонент TFgPositionAnimation, созданный для анимации свойств типа TPosition.

    Я сам пробовал использовать этот компонент - работал нормально.

  14. Доброго времени суток.

    На Embarcadero Delphi 11 Alexandria при компиляции проекта стал замечать такие сообщения:

    Порядок действий:

    1. Создаю проект
    2. В настройках проекта включаю параметр Link with runtime packages при использовании конфигурации All Platforms - All Configurations (этот параметр мне нужен из-за одной библиотеки, которая уже предварительно скомпилирована и у меня имеются лишь BPL и DCP файлы, без DCU)
    3. Компилирую под WIn32 (debug) - все нормально
    4. Компилирую под Win32 (release) - все нормально
    5. Компилирую под Win64 (debug) - все нормально
    6. Компилирую под Win64 (release) - все нормально
    7. Возвращаюсь обратно на Win32
    8. Компилирую под Win32 (debug) - ошибка (первое сообщение)
    9. Компилирую под Win32 (release) - все нормально
    10. Перехожу на Win64
    11. Компилирую под Win64 (debug) - все нормально
    12. Компилирую под Win64 (release) - ошибка (второе сообщение)

    Потом ошибки могут наоборот появляться например Win32 Debug нормально скомпилируется, а Win32 Release с ошибкой. То же самое касается и Win64, там такая же история.

    Если ошибка не появляется, то можно зайти в настройки проекта, что-нибудь изменить (например я включал\отключал Use Debug .dcu) ну или пройти зайти в настройки проекта и выйти. Тогда с большой вероятностью ошибка появится при компиляции

     

    Сообщение 1:

    [dcc32 Fatal Error] Project1.dpr(5): E2213 Bad packaged unit format: c:\program files (x86)\embarcadero\studio\22.0\lib\Win32\release\vcl.dcp.Vcl.Forms - Expected version: 35.0, Windows Unicode(x86) Found version: 7.54, Unk(ARM)

     

    Сообщение 2:

    [dcc64 Fatal Error] Project1.dpr(5): E2213 Bad packaged unit format: c:\program files (x86)\embarcadero\studio\22.0\lib\Win64\debug\vcl.dcp.Vcl.Forms - Expected version: 35.0, Windows Unicode(x64) Found version: 90.95, MaxOSX NX Language(ARM)

     

    Собственно вопрос следующий: могли бы вы, кто-нибудь проверить у себя такое же (желательно именно на Delphi 11 Alexandria), т.е проделать мой порядок действий.

     

    Обращу внимание на то, что если параметр Link with runtime packages отключить, то все сразу становится нормальным, компиляция происходит в штатном режиме и никаких сообщений с ошибкой не вываливается.

  15. Доброго времени суток.

    Интересует такой вопрос.
    Вот не так давно (9 сентября где-то) вышла новая 11.0 Alexandria, и там опять минимально поддерживаемую версию подняли. Вроде бы до Android 8.1.

    И вообще Embarcadero с каждым релизом поднимает минимальную поддерживаемую версию Android.

    Интересно, эта поддержка реализуется на стороне компилятора или самого FireMonkey?

    т.е например если на стороне FireMonkey, то например теоретически может быть возможно собрать приложение минуя FireMonkey для какого-нибудь Android 5.1 на Rad Studio 11.0.

    Спасибо.

  16. 12 часов назад, slav_z сказал:

    господи, как же я давно не писал ничего на vcl

    Это решение подразумевает наличие этих файлов на диске? (к сожалению, сейчас проверить это решение не имею возможности).


    Просто у меня архив с нестандартной структурой и хотелось бы получить иконки файлов без их извлечения на диск. Например (насколько я знаю), так работает WinRar и 7-zip, они не извлекают файлы для того получить их иконки. Можно открыть архив на несколько гигабайт и он корректно покажет иконки файлов. Вот чего я хочу добиться, чтобы отобразить иконку файла, но если самого файла на диске нет.

    P.S: Даже смотрел в сторону еще одного костыльного решения: создавать пустые файлы, которые содержатся в архиве и тогда вполне корректно смогу получить их иконки.

  17. Доброго времени суток. Имеется необходимость получить иконки файлов. Суть такая:

    Имеются некие файлы-архивы, с нестандартной структурой файла. Проще говоря, я пишу приложение-архиватор для своего типа файлов.

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

    Например: у меня установлен AIMP и все поддерживаемые AIMP'ом файлы отображаются его иконками. EXE, DLL, BAT, CMD и др - системными иконками.
    Можно поискать готовые решения в виде ShellListBox, ShellListView и т.д., но они не подойдут, как минимум потому, что файлы, которыми я заполняю список не распакованы, они находятся в файле-архиве.

    Соответственно функции по типу ExtractIcon (ссылка на docs.microsoft.com) и др. не подходят, файла-то нет. Я нашел одно решение - поиск иконок по реестру. В принципе это работает, но далеко не так, как хотелось бы... 

    Информация в реестре почему-то порой не соответствует указанным мною параметрам. Например, в реестре у меня иконки подгружаются из файла VLC.exe. Изначально так оно и было, пока я не сменил их на AIMP, в проводнике это привело к нужному результату (иконки сменились), а вот в реестре до сих пор отображается VLC, соответственно, когда я ищу иконку по расширению .mp3, я нахожу иконку VLC, хотя настройки ассоциации формата .mp3 явно указывают на AIMP. 

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

    Собственно вопрос: В какую сторону копать для решения данной проблемы? (Решения "только для FireMonkey" не подойдут, ибо нужны именно WinAPI-решения).

    Код получения иконки по формату файла: (не самое лучшее решение, это очевидно).

    Спойлер
    
    function GetIcon(aExtension: string): HICON;
      begin
        if reg = nil then
            reg := TRegistry.Create();
    
        reg.RootKey := HKEY_CLASSES_ROOT;
    
        var iconPath: TArray<string> := [];
    
        if (aExtension = '') then
          begin
            reg.OpenKey('Folder\DefaultIcon', false);
            iconPath := reg.ReadString('').Split([',']);
            reg.CloseKey();
            FreeAndNil(reg);
            Exit(ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1])));
          end
        else
          begin
            reg.OpenKey(aExtension, false);
            var iconRef: string := reg.ReadString('');
            reg.CloseKey();
            reg.OpenKey(iconRef, false);
            if (reg.KeyExists('DefaultIcon')) then
              begin
                reg.OpenKey('DefaultIcon', false);
                iconPath := reg.ReadString('').Split([',']);
                if (iconPath[0].StartsWith('"') or iconPath[0].EndsWith('"')) then
                    iconPath[0] := iconPath[0].Trim(['"']);
    
                reg.CloseKey();
                FreeAndNil(reg);
                Exit(ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1])));
              end;
          end;
        reg.CloseKey();
        reg.OpenKey('Unknown\DefaultIcon', false);
        iconPath := reg.ReadString('').Split([',']);
        Result := ExtractIcon(0, PChar(iconPath[0]), StrToInt(iconPath[1]));
      end;

     

    Прикрепляю небольшой пример использования этой функции.

    Project1.zip

  18. 3 часа назад, Slym сказал:

    там еще дефайны стоят #if defined(WINDOWS) && !defined(WINDOWLESS)
    т.к. нельзя пропускать функции в структуре - надо точно знать с какими дефайнами длл сбилдена.
    если лень описывать ненужную функцию делай заглушкой SciterGetPPI: pointer;  - повторюсь пропускать нельзя

    WINDOWLESS - это Lite версия библиотеки, я же использую обычную версию, так что все правильно в этом случае. 

  19. 1 час назад, Slym сказал:

    а где тут stdcall?

    type
      PSciterAPI = ^ISciterAPI;
      ISciterAPI = packed record
        version: UINT;
        SciterClassName: function(): LPCWSTR;stdcall;
        SciterVersion: function(major: BOOL): UINT;stdcall;
      end;

    Здесь просто забыл дописать, ибо писал это все с телефона, да и времени особо не было. В коде же stdcall есть обязательно перед каждой функцией библиотеки

  20. 4 часа назад, Slym сказал:

    макросы разворачиваем в уме:
    sciter-x-api.h UINT
    SCFN( SciterVersion )(BOOL major);
    sciter-x-types.h  #
    define SCFN(name) (__stdcall *name)
    итог:
    SciterVersion: function(major:
    bool) UINT; stdcall;
    и всетаки попробуй bool оставить

    Начну по порядку:
    1. SCFN я сразу же расшифровал как: __stdcall *НАЗВАНИЕ ФУНКЦИИ* - например __stdcall SciterVersion(bool major)

    2. Я изначально использовал тип BOOL в Delphi, но так как его значение true является (-1), то я перешел на Integer, ведь функции и с ним работают нормально, по крайней мере что бы я не проверил подставив Integer вместо BOOL, результат был ожидаемым и ничего нигде не падало с каким-либо исключением. Из-за того, что значение BOOL (true) является -1, функции не считали его как true, они принимали значения (true - 1, false - 0)? Соответственно функция SciterVersion(true) (BOOL) возвращала то же, что и SciterVersion(false), а вот когда я перешел на Integer, результат функции SciterVersion(1) и SciterVersion(0) стал отличаться.

    К сожалению, но ничего из этого мне не помогает, и вообще было предпринято мною изначально. 
    Пока-что, единственный мой выход из ситуации *костыль* в виде отдельной DLL-библиотеки-посредника, с которой связывается мой Delphi-код, а та в свою очередь вызывает одноименный метод структуры ISciterAPI в нужной мне библиотеке и возвращает мне через этого *посредника* мне обратно в Delphi-код. Выглядит ужасно, но это работает...

    Хотелось бы все-таки обойтись без этого костыля. Сейчас у меня работает это примерно так:

    1. Delphi (вызывает функцию SciterVersion(1)) из DLL-посредника

    2. DLL-посредник связывается с основной библиотекой и вызывает оттуда одноименный метод структуры ISciterAPI

    3. DLL-посредник возвращает мне результат, полученный из основной функции.

    Минус этого подхода для меня в том, что после серьезного обновления библиотеки, или любого другого, которое хоть как-то заденет API, мне придется переписывать DLL-посредника для соответствия последним изменениям API Sciter. А так же придется переписывать код Delphi для соответствия последним моим изменениям DLL-посредника. ЭТО КРАЙНЕ НЕУДОБНО

     

  21. Всем доброго времени суток, имеется проблема...

    Есть библиотека sciter, я хочу ее использовать в Delphi, но имеющиеся там *привязки*(bindings) ориентированы на Delphi 7 (но это не самое главное, они рассчитаны на версию библиотеки 3.x, в то время, как библиотека уже давно 4.4.x, собственно там много чего нет).
    Но у библиотеки есть C PLAIN API, при помощи которого можно запросто подружить ее с Delphi, чем я собственно и занимаюсь, но возникла проблема..

    Есть основная функция, которая возвращает структуру с кучей других функций (ISciterAPI), она в принципе работает, некоторые функции я пробовал из нее вызывать и они работали отлично, но работают лишь несколько первых функций нормально, остальные же сыплются на Access Violation, хотя на других языках это работает нормально. 

    Структура выглядит таким образом, потом при помощи другой функции возвращается указатель на эту структуру ISciterAPI* (В самой структуре функций намного больше).

    typedef struct ISciterAPI {
      UINT version;
      LPCWSTR SciterClassName(void);
      UINT SciterVersion(BOOL major);
    };
    typedef ISciterAPI* LPSciterAPI;

    В Delphi я все оформляю так:

    type
      PSciterAPI = ^ISciterAPI;
      ISciterAPI = packed record
        version: UINT;
        SciterClassName: function(): LPCWSTR; // LPCWSTR - PWideChar;
        SciterVersion: function(major: Integer): UINT; // Использовал до этого BOOL, но наткнулся на статью, где рассказывалось о том, что он немного странно работает, мол BOOL false = 0, а BOOL true = -1; Поэтому напрмиер функция SciterVersion у меня не работала правильно, но при использовании Integer все стало нормально работать.
      end;

    Но, как я уже сказал ранее - только некоторые функции работают, остальные падают с исключением ACCESS VIOLATION.

    Почему так может быть?

    P.S: Единственный пока рабочий для меня вариант - написание отдельной библиотеки, которая выносит все эти функции в экспорт, соответственно их теперь можно вызывать непосредственно из самой библиотеки, минуя ISciterAPI, но минусы такого подхода в том, что эта библиотека по сути является посредником между программой на Delphi и Sciter...

×
×
  • Создать...