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

dnekrasov

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

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

  • Посещение

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

    52

Весь контент dnekrasov

  1. var bmd: TBitmapData; bmp: TBitmap; c, c1: TAlphaColor; x, y: Integer; ... bmp.Map(TMapAccess.ReadWrite, bmd); try c1 := bmd.GetPixel(x, y); bmd.SetPixel(x, y, c); finally bmp.Unmap(bmd); end;
  2. А можно ещё так: ListView1.Items[0].Index := 1; ListView1.Items[1].Index := 0; ListView1.Items.Sort(TComparer<TListViewItem>.Construct( function(const ALeft, ARight: TListViewItem): Integer begin Result := ALeft.Index - ARight.Index; end)); Поменять-то поменяет, только на сколько обоснован вызов Sort в этой ситуации - решать Вам.
  3. Как-то так: with lvObjects.Items.Add do begin Text := 'Footer'; Purpose := TListItemPurpose.Footer; end;
  4. В чём проблема - используйте Queue или Synchronize
  5. А зачем менять. Можно же просто засинхронизировать: TThread.ForceQueue(nil, procedure begin MaxSize := CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize); end);
  6. А зачем Вам использовать SetWindowRgn? Если у Вас есть битмапки, то Ваша задача правильно преобразовать их в регионы (HRGN). Создать какой-то класс, который будет сопоставлять эти битмапки и созданные в памяти объекты HRGN + содержать в себе информацию о Z-координате битмапки. Далее отрисовать битмапки на форме. ну и и по клику просто отследить какой регион содержит точку клика, в соответсвии с Z-Order. Я понимаю, хочется как раньше - любому TWinControl дал SetWindowRgn - и все ОК, но проблема в том, что в Firemonkey контролы не имеют хэндла да и кидать кучу контролов один на другой с одной целью - определить в какой из них попал клик, по-моему не очень хорошее решение.
  7. Если игра под Windows, то самый простой выход (по моему мнению) - работа с регионами. Ведь каждый объект это по сути дела какой-то замкнутый полигон, а функции CreatePolygonRgn и PtInRegion еще никто не отменял. А вообще функций для работы с регионами немало, так что почитайте о них на MSDN. Если не хотите использовать WinAPI-шные функции - работайте с полигонами. Мне когда-то очень помогла библиотека AlgLib - из нее можно вытянуть много полезных функций, чтобы самому не реализовывать алгоритмы.
  8. @ENERGY Хорошая привычка . У меня тоже она есть, вот только слово - Operation . Насчет вызова в отдельном потоке - была у меня недавно задачка: на всех открытых в данный момент окнах обновлять некую инфу с заданным интервалом. Так я её реализовал вызовом одной процедуры изнутри постоянно крутящегося потока. Но эту инфу надо было отобразить еще и при открытии формы - вот тогда мне очччень помог метод ForceQueue Кстати, для меня это не спор, а обыкновенный обмен опытом, ведь спорить о том как и что лучше реализовать в большинстве случаев бесполезно, а вот знать как реализовать ту или иную задачу разными способами - просто необходимо.
  9. @ENERGY, я говорил об этой процедуре, а ее можно вызвать откуда угодно. Ведь задача и состоит в том, чтобы в теле этой процедуры синхронизировать обращение к элементам GUI с главным потоком. Ведь кто нам мешает к ней обратиться следующим образом: T := TThread.CreateAnonymousThread( procedure begin setLogo(ListView, 'name', 'url', index); end); T.start; Кстати, в этом случае, внутри нее можно вообще избавиться от CreateAnonymousThread
  10. Это верно только в том случае, если мы заранее знаем, что процедура SetLogo будет всегда вызываться только из основного потока. Если что-то менять - я бы код T := TThread.CreateAnonymousThread( procedure begin TThread.Synchronize(TThread.CurrentThread, procedure() begin ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png'); end); end); T.start; заменил бы следующим: TThread.ForceQueue(TThread.CurrentThread, procedure() begin ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png'); end);
  11. Маленький примерчик CopyFromBitmap.zip
  12. Возникла та же проблема. Решение довольно простое. Первый наследник от TFrame должен обязательно идти с визуальной частью (*.fmx). В последующих наследниках всегда наследовать не только класс фрейма, но и сам фрейм (перейти в текстовое отображение фрейма и в самом начале вместо object написать inhereted. Ну или просто создавать через File->New->Other...| DelphiProjects->Inheritable Items->[Ваш фрейм]). У меня сейчас в проекте доходит до 6-ти уровней наследования фреймов и все отрабатывает на ура. Единственная проблема как была во всех версиях дельфи так и осталась: при открытии фрейма в дизайнере должны быть открыты все его предки
  13. Чтобы просто избавиться от горизонтального скроллбара нужно обработать событие OnCalcContentBounds. Что-то типа этого: procedure TMainForm.TreeView1CalcContentBounds(Sender: TObject; var ContentBounds: TRectF); begin ContentBounds.Width := TreeView1.Content.BoundsRect.Width; // Нужно учесть еще и ширину вертикального скроллбара end;
  14. В Berlin и Tokyo AddFontResource и RemoveFontResource прекрасно отрабатывают, только вызывать их надо до Application.Run. Кстати, лучше использовать AddFontResourceEx и RemoveFontResourceEx с флагом FR_NOT_ENUM - тогда надобность в SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) отпадает.
  15. А зачем вообще задаются вопросы? Если бы было все просто - не спрашивал бы. Нужно один раз решить проблему и больше к этому не возвращаться - приложение развивается, стили меняются, добавляются и каждый раз не хочется учитывать этот момент. Здесь предложили вариант, который не зависит от стиля - но это (по моему мнению) - костыль, но пока работает. Да и менять в стиле нужно много - посмотрите сколько видов стиля для TSpeedButton (ведь правильно говорят - "Лень - двигатель прогресса" ) Первое, что испробовал - с FixedHeight не работает. А вообще - хочется сделать механизм, который бы в рантайме, в момент применения стиля, добавлял бы копию уже имеющегося стиля для контрола и делал бы с этой копией необходимые мне манипуляции, в том числе изменение FixedHeight. Все работает, кроме FixedHeight.
  16. А каким образом добраться до этих свойств в рантайме?
  17. Это глобальная переменная, которая объявлена в SysInit: HInstance: HINST; { Handle of this instance }
  18. Вот код, который вернёт путь к исполняемому файлу (тот, который деплоится в "Contents\MacOS\") function GetModuleFName(AModule: Cardinal): string; begin SetLength(Result, MAX_PATH); GetModuleFileName(AModule, @Result[1], MAX_PATH); SetLength(Result, StrLen(PChar(Result))); end; function GetModuleFolder: string; begin Result := IncludeTrailingPathDelimiter(ExtractFilePath(GetModuleFolder(HInstance))); end; :
  19. Лучше использовать System.IOUtils.TPath.GetLibraryPath Встроенный Zip тоже может разбивать по томам. Например команда "zip -r -s 50 ArchiveName.zip FolderName/" упакует всю папку "FolderName" и разобьёт архив по файлам весом 50Mb
  20. По 1-му вопросу для MacOS: function CheckRunning: Boolean; var sl: TStringList; iCount: Integer; s: String; begin sl := TStringList.Create; try GetRunningAplications(sl); iCount := 0; for s in sl do if SameText(s, APP_BundleID) then // APP_BundleID - константа с BundleID приложения Inc(iCount); Exit(iCount < 2) finally sl.Free; end; end; procedure GetRunningAplications(AList: TStrings); var WorkSpace: NSWorkSpace; App: NSRunningApplicationEx; i: Integer; list: NSArray; begin WorkSpace := TNsWorkspace.Wrap(TNsWorkSpace.OCClass.SharedWorkspace); list := Workspace.runningApplications; if (list <> nil) and (list.count > 0) then begin for i := 0 to list.count-1 do begin App := TNSRunningApplicationEx.Wrap(list.objectAtIndex(i)); if App.bundleIdentifier <> nil then AList.Add(string(App.bundleIdentifier.UTF8String)) else AList.Add(String(App.executableURL.path.UTF8String)); end; end; end; Ответ на 3-ий вопрос сам уже долго ищу
  21. EqualRect(Control1.BoundsRect.Intersect(Control2.BoundsRect), Control2.BoundsRect) Если True, то Control2 не вышел за пределы Control1, иначе - вышел
  22. Конечно будет очень мелкое, ведь Вы устанавливаете 1200 точек на дюйм и ширина листа А4 в портретном режиме у Вас получается чуть меньше 100000 точек. Исходя из этого просто задайте адекватные значения для h, w, x0, y0, x, y и все у Вас будет в порядке. Например, для печати битмапки, я ипользую такой код: var bmp: TBitmap; SrcRect, DestRect: TRectF; DPI: TPoint; cx, cy: Extended; begin Printer.ActivePrinter.SelectDPI(1200, 1200); DPI := Printer.ActivePrinter.DPI[Printer.ActivePrinter.ActiveDPIIndex]; {$IFDEF MSWINDOWS} cx := DPI.X / GetDeviceCaps(GetDC(GetDesktopWindow), LOGPIXELSX); cy := DPI.Y / GetDeviceCaps(GetDC(GetDesktopWindow), LOGPIXELSY); {$ENDIF} bmp := TBitmap.Create(0, 0); try FEditor.GetAsBitmap(bmp); SrcRect := TRectF.Create(0, 0, bmp.Width * cx, bmp.Height * cy); DestRect := TRectF.Create(0, 0, Printer.PageWidth, Printer.PageHeight); if SrcRect.Width / SrcRect.Height > DestRect.Width / DestRect.Height then Printer.Orientation := TPrinterOrientation.poLandscape else Printer.Orientation := TPrinterOrientation.poPortrait; if (SrcRect.Width < DestRect.Width) and (SrcRect.Height < DestRect.Height) then begin DestRect.Left := (DestRect.Width - SrcRect.Width) / 2; DestRect.Width := SrcRect.Width; DestRect.Top := (DestRect.Height - SrcRect.Height) / 2; DestRect.Height := SrcRect.Height; end else begin SrcRect.Fit(DestRect); DestRect := SrcRect; end; Printer.BeginDoc; try Printer.Canvas.DrawBitmap(bmp, TRectF.Create(0, 0, bmp.Width, bmp.Height), DestRect, 1); finally Printer.EndDoc; end; except Printer.Abort; end; FreeAndNil(bmp); end;
×
×
  • Создать...