dnekrasov

Пользователи
  • Публикации

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

  • Посещение

  • Days Won

    7

dnekrasov last won the day on 8 мая

dnekrasov had the most liked content!

О dnekrasov

  • Звание
    Продвинутый пользователь
  • День рождения 21.02.1974

Информация

  • Пол
    Мужчина
  • Город
    Минск

Посетители профиля

487 просмотров профиля
  1. А зачем Вам использовать SetWindowRgn? Если у Вас есть битмапки, то Ваша задача правильно преобразовать их в регионы (HRGN). Создать какой-то класс, который будет сопоставлять эти битмапки и созданные в памяти объекты HRGN + содержать в себе информацию о Z-координате битмапки. Далее отрисовать битмапки на форме. ну и и по клику просто отследить какой регион содержит точку клика, в соответсвии с Z-Order. Я понимаю, хочется как раньше - любому TWinControl дал SetWindowRgn - и все ОК, но проблема в том, что в Firemonkey контролы не имеют хэндла да и кидать кучу контролов один на другой с одной целью - определить в какой из них попал клик, по-моему не очень хорошее решение.
  2. Если игра под Windows, то самый простой выход (по моему мнению) - работа с регионами. Ведь каждый объект это по сути дела какой-то замкнутый полигон, а функции CreatePolygonRgn и PtInRegion еще никто не отменял. А вообще функций для работы с регионами немало, так что почитайте о них на MSDN. Если не хотите использовать WinAPI-шные функции - работайте с полигонами. Мне когда-то очень помогла библиотека AlgLib - из нее можно вытянуть много полезных функций, чтобы самому не реализовывать алгоритмы.
  3. @ENERGY Хорошая привычка . У меня тоже она есть, вот только слово - Operation . Насчет вызова в отдельном потоке - была у меня недавно задачка: на всех открытых в данный момент окнах обновлять некую инфу с заданным интервалом. Так я её реализовал вызовом одной процедуры изнутри постоянно крутящегося потока. Но эту инфу надо было отобразить еще и при открытии формы - вот тогда мне очччень помог метод ForceQueue Кстати, для меня это не спор, а обыкновенный обмен опытом, ведь спорить о том как и что лучше реализовать в большинстве случаев бесполезно, а вот знать как реализовать ту или иную задачу разными способами - просто необходимо.
  4. @ENERGY, я говорил об этой процедуре, а ее можно вызвать откуда угодно. Ведь задача и состоит в том, чтобы в теле этой процедуры синхронизировать обращение к элементам GUI с главным потоком. Ведь кто нам мешает к ней обратиться следующим образом: T := TThread.CreateAnonymousThread( procedure begin setLogo(ListView, 'name', 'url', index); end); T.start; Кстати, в этом случае, внутри нее можно вообще избавиться от CreateAnonymousThread
  5. Это верно только в том случае, если мы заранее знаем, что процедура 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);
  6. Маленький примерчик CopyFromBitmap.zip
  7. Возникла та же проблема. Решение довольно простое. Первый наследник от TFrame должен обязательно идти с визуальной частью (*.fmx). В последующих наследниках всегда наследовать не только класс фрейма, но и сам фрейм (перейти в текстовое отображение фрейма и в самом начале вместо object написать inhereted. Ну или просто создавать через File->New->Other...| DelphiProjects->Inheritable Items->[Ваш фрейм]). У меня сейчас в проекте доходит до 6-ти уровней наследования фреймов и все отрабатывает на ура. Единственная проблема как была во всех версиях дельфи так и осталась: при открытии фрейма в дизайнере должны быть открыты все его предки
  8. Чтобы просто избавиться от горизонтального скроллбара нужно обработать событие OnCalcContentBounds. Что-то типа этого: procedure TMainForm.TreeView1CalcContentBounds(Sender: TObject; var ContentBounds: TRectF); begin ContentBounds.Width := TreeView1.Content.BoundsRect.Width; // Нужно учесть еще и ширину вертикального скроллбара end;
  9. В Berlin и Tokyo AddFontResource и RemoveFontResource прекрасно отрабатывают, только вызывать их надо до Application.Run. Кстати, лучше использовать AddFontResourceEx и RemoveFontResourceEx с флагом FR_NOT_ENUM - тогда надобность в SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0) отпадает.
  10. А зачем вообще задаются вопросы? Если бы было все просто - не спрашивал бы. Нужно один раз решить проблему и больше к этому не возвращаться - приложение развивается, стили меняются, добавляются и каждый раз не хочется учитывать этот момент. Здесь предложили вариант, который не зависит от стиля - но это (по моему мнению) - костыль, но пока работает. Да и менять в стиле нужно много - посмотрите сколько видов стиля для TSpeedButton (ведь правильно говорят - "Лень - двигатель прогресса" ) Первое, что испробовал - с FixedHeight не работает. А вообще - хочется сделать механизм, который бы в рантайме, в момент применения стиля, добавлял бы копию уже имеющегося стиля для контрола и делал бы с этой копией необходимые мне манипуляции, в том числе изменение FixedHeight. Все работает, кроме FixedHeight.
  11. А каким образом добраться до этих свойств в рантайме?
  12. Это глобальная переменная, которая объявлена в SysInit: HInstance: HINST; { Handle of this instance }
  13. Вот код, который вернёт путь к исполняемому файлу (тот, который деплоится в "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; :
  14. Лучше использовать System.IOUtils.TPath.GetLibraryPath Встроенный Zip тоже может разбивать по томам. Например команда "zip -r -s 50 ArchiveName.zip FolderName/" упакует всю папку "FolderName" и разобьёт архив по файлам весом 50Mb
  15. По 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-ий вопрос сам уже долго ищу