Замечания и предложения

Вместо GetString есть .SubString.

У GetString и SubString разные реализации и функции

А поясните на примере пожалуйста, какую подстроку вы вырезаете из ресурсов

В смысле? Что по вашему .SubString делает? Вы уверены что смотрите не только на первую перегрузку?

Конкретно из ресурсов - никакую.Я из имени вырезаю,для свойства Name

Пример приведите

Да,уверен. Посмотрите тело моей функции и сравните.

PName := GetString(name, 1, name.LastIndexOf(’.’));

Я сказал про .SubString именно потому что увидел тело функции.

А вообще тут и name.Remove(name.LastIndexOf('.')) сработает. Хотя он сам - вызывает name.SubString(0,name.LastIndexOf('.')).

По моему имелся в виду пример на конкретных строках.


P.S. А ещё есть System.IO.Path.GetFileNameWithoutExtension.

1 лайк

Думаю уже не нужно,т.к. я меняю код

Да. Вот приведите мне его пожалуйста - код я напишу

Уже не нужно,я убрал GetString. Если хотите как расширение добавить,то это обычный срез для строк,просто в виде функции

Он просто отрезал от строки часть, начиная с последнего символа точки. То есть брал имя файла ресурса без расширения.

Ну, я всё ещё считаю, что правильнее создавать картинку именно из потока, а не имени ресурса. Как получать поток - это вопрос к программисту.

Ну а про свойство имени - я не совсем понимаю зачем оно. Ну, в любом случае - оно не применимо к картинкам, созданным из ресусра.
Поэтому, как я сказал выше - имеет смысл или присваивать ему nil, или кидать исключение, когда пользователь пытается получить имя для картинки из ресурса.

Ну вот пример,зачем нужно это свойство. Лично мне потребовалось. Я делал практическую работу.И что бы пользователю было легче ориентироваться в программе я сделал всплывающие подсказки при наведении на картинку,и что бы не прописывать каждой картинке по подсказке я сделал свойство Name. И это решило проблемы с подсказками.

Вот исправленный код:

PictureWPF = class(ObjectWPF)
private
  PName: string;
  function CreateBitmapImage(fname: string) := new BitmapImage(new System.Uri(fname, System.UriKind.Relative)); 
  procedure Rest(x, y, w, h: real; b: BitmapImage);
  begin
    var im := new System.Windows.Controls.Image();
    im.Source := b;
    im.Width := w;
    im.Height := h;
    
    InitOb(x, y, w, h, im);
  end;
  
  procedure InitOb3(x, y, w, h: real; fname: string; ResB: boolean);
  begin
    PName := System.IO.Path.GetFileNameWithoutExtension(fname);
    
    var b: BitmapImage;
    if ResB
    then begin
      b := new BitmapImage();
      b.BeginInit();
      b.StreamSource := GetResourceStream(fname);
      b.EndInit();
    end
    else b := CreateBitmapImage(fname);
    Rest(x, y, w, h, b);
  end;
  
  procedure InitOb2(x, y: real; fname: string; ResB: boolean);
  begin
    PName := System.IO.Path.GetFileNameWithoutExtension(fname);
    
    var b: BitmapImage;
    if ResB
    then begin
      b := new BitmapImage();
      b.BeginInit();
      b.StreamSource := GetResourceStream(fname);
      b.EndInit();
    end
    else b := CreateBitmapImage(fname);
    Rest(x, y, b.PixelWidth, b.PixelHeight, b);
  end;
  
  function GetInternalGeometry: Geometry; override;
  begin
    var r := Rect(0, 0, Width, Height);
    Result := new RectangleGeometry(r);
  end;

public
  function Element := ob as System.Windows.Controls.Image;
    /// Создает рисунок из файла fname с координатами левого верхнего угла (x,y)
  constructor(x, y: real; fname: string; ResB: boolean := false):= Invoke(InitOb2, x, y, fname, ResB);
    /// Создает рисунок из файла fname с координатами левого верхнего угла (x,y) и размерами (w,h)
constructor(x, y, w, h: real; fname: string; ResB: boolean := false):= Invoke(InitOb3, x, y, w, h, fname, ResB);
    /// Создает рисунок из файла fname с координатой левого верхнего угла, заданной точкой p
constructor(p: GPoint; fname: string; ResB: boolean := false):= Invoke(InitOb2, p.x, p.y, fname, ResB);
    /// Создает рисунок из файла fname  с координатой левого верхнего угла, заданной точкой p, и размерами (w,h)
constructor(p: Point; w, h: real; fname: string; ResB: boolean := false):= Invoke(InitOb3, p.x, p.y, w, h, fname, ResB);
    /// Декоратор текста объекта
function SetText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): PictureWPF  
:= inherited SetText(txt, size, fontname, c) as PictureWPF;
    /// Декоратор поворота объекта
  function SetRotate(da: real): PictureWPF := inherited SetRotate(da) as PictureWPF;
  
  property Name: string read PName write PName := value;
end;

Я не смог придумать новые описания,по этому оставил старые.

Если одному объекту должны быть сопоставлены другие объекты - используйте или словарь, или обёртку:

  PictureWithText = sealed class
    p: PictureWPF;
    s: string;
    
  end;

А сохранять это как свойство картинки - неправильно, потому что картинка которую уже загрузили в оперативную память никак не касается того, откуда её загрузили.

Уже менять что-то поздно.Если разработчики захотят убрать это свойство,это их дело

Я не говорил об убирании свойства. Я говорю что нечего костыли поверх пилить.

А где тут костыль?Я вам показал пример,где это может понадобится

@Admin

https://pascalabcnet.github.io/mydoc_for_school_teachers.html#циклы-по-массиву

(если индексы не вадны и мы не меняем массив)

https://pascalabcnet.github.io/mydoc_for_school_teachers.html#операции-с-массивами

Раздел как то не к месту. Наверное надо его выше поставить? А то получается:

А сейчас мы объясним лямбды:
*рандомная вставка операций с массивами*
*сами лямбды*