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

SerhioUser

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

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

  • Посещение

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

  1. Добрый день.

    Как в FMX при перерисовке объекта включить/отключить привязку к вертикальной синхронизации (v-sync) развертки экрана? Есть ли такая возможность в FMX? (В OpenGL и DirectX - есть)

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

  2. Благодарю, Евгений Корепов!

    Вот функция GetApkVersion() на C++ для получения версии APK-файла, и слегка подкорректированная вышеописанная функция запуска:

    String __fastcall ShellExecutePipe(String CommandLine, String AWorkDir = "C:\\", UINT Flag = SW_HIDE)
    {
    	TSecurityAttributes SA;
    	TStartupInfo SI;
    	TProcessInformation PI;
    	HANDLE StdOutPipeRead, StdOutPipeWrite;
    	bool WasOK;
    	char Buffer[256];
    	unsigned long BytesRead;
    	String WorkDir;
    	bool Handle;
    	String AOutputLine;
    	String Result;
    
      SA.nLength = sizeof(SA);
      SA.bInheritHandle = true;
      SA.lpSecurityDescriptor = NULL;
      CreatePipe(&StdOutPipeRead, &StdOutPipeWrite, &SA, 0);
      try
      {
        setmem(&SI, sizeof(SI), 0);
        SI.cb = sizeof(SI);
        SI.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
        SI.wShowWindow = Flag;
        SI.hStdInput = (unsigned)GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
        SI.hStdOutput = (unsigned int)StdOutPipeWrite;
        SI.hStdError = (unsigned int)StdOutPipeWrite;
        WorkDir = AWorkDir;
        Handle = CreateProcess(NULL, CommandLine.c_str(),
                                NULL, NULL, true, 0, NULL,
                                WorkDir.c_str(), (STARTUPINFO*)&SI, &PI);
      }
      catch(Exception &e)
      {
      }
    
      CloseHandle(StdOutPipeWrite);
    
      if (Handle)
      {
        try
        {
          do
          {
            WasOK = ReadFile(StdOutPipeRead, Buffer, 50, &BytesRead, NULL);
            if(BytesRead > 0)
            {
              Buffer[BytesRead] = 0;
              AOutputLine = Buffer;
              Result = Result + AOutputLine;
            }
          }while(WasOK && (BytesRead != 0));
          WaitForSingleObject(PI.hProcess, INFINITE);
    	}
        __finally
        {
          CloseHandle(PI.hThread);
          CloseHandle(PI.hProcess);
        }
      }
    
      CloseHandle(StdOutPipeRead);
      return Result;
    }
    
    //---------------------------------------------------------------------------
    String __fastcall GetShortName(String sLongName)
    {
    	String ret;
    	String sShortName;
    	int nShortNameLen;
    
    	sShortName.SetLength(MAX_PATH);
    	nShortNameLen = GetShortPathName(
    		sLongName.c_str(), sShortName.c_str(),
    		MAX_PATH - 1);
    	if (nShortNameLen != 0)
    	{
    		sShortName.SetLength(nShortNameLen);
    		ret = sShortName;
    	}
    	return ret;
    }
    
    //---------------------------------------------------------------------------
    String __fastcall GetApkVersion(String FileName)
    {
    	String ret;
    	String AppPath = GetShortName(ExtractFileDir(Application->ExeName));
    	FileName = GetShortName(FileName);
    	if(FileName != "")
    	{
    	  String cmd = (String)"cmd /c \""+ AppPath + "\\aapt.exe\"" + " dump badging " + FileName;
    	  String res = ShellExecutePipe(cmd, AppPath);
    	  TStringList *sl = new TStringList;
    	  sl->Delimiter = ' ';
    	  sl->DelimitedText = res;
    	  ret = AnsiDequotedStr(sl->Values["versionName"], '\'');
    	  if(ret != "")
    		ret += ".";
          ret += AnsiDequotedStr(sl->Values["versionCode"], '\'');
          delete sl;
        }
        return ret;
    }
    
    //---------------------------------------------------------------------------

    Всем спасибо за участие.

  3. В общем работает так:

    WinExec("cmd /c aapt.exe dump badging path\\file.apk > text.txt", SW_HIDE);

    Запускается по тихому и создает text.txt, из которого можно выудить информацию о версии. Жаль, что нельзя этот файл получать напрямую в память, а не на диск - лишние операции, создающие тормоза.

  4. Попытался извлечь из APK-файла файл AndroidManifest.xml с помощью 7zip и winrar. Как архив apk открывается, а вот содержимое действительно похоже на зашифрованное. У AndroidManifest.xml даже размер не соответствует оригинальному AndroidManifest.xml, который туда помещала студия. Кто-то может у себя это проверить?

    TZipFile вернул аналогичное шифрованное содержимое.

    Походу  aapt dump badging единственный вариант...

  5. 6 минут назад, krapotkin сказал:

    не может быть такого

    весь смысл cmd в параметрах. сам он ничего не делает, так что ошибка на стороне программиста..

    Пуск->Выполнить

    Дальше пишем "cmd.exe dir"

    Открывается консоль и фСё! :) Сам в шоке... (У меня win 8.1)

    1 минуту назад, Rusland сказал:

    Про зашифрованный apk ни разу не слышал...

    Я, честно говоря, тоже... возможно тот чел. что-то не так делал...

  6. 13 часов назад, Major сказал:

    где это вы читали?

    Вот здесь человек не мог открыть apk архиватором. Конечно возможно он что-то делал не так.

    Мои apk-шки архиваторы открывают нормально, и это обнадеживает.

    14 часов назад, ENRGY сказал:

    Вот эта команда "> mytextfile.txt" 100% сохранит весь вывод консоли в файл.

    Я ж написал, что я так пробовал с самого начала. Только не написал, что в консоли отрабатывает корректно.

    А из ShellExecute и из WinExec в файл не сохраняет (это я писал). Одна и та-же команда. Просто выводит на экран, как будто "> mytextfile.txt" не прописано.

    Сейчас буду разбираться, что умеет TZipFile.

  7. 1 минуту назад, ENRGY сказал:

     

    Ну какие под Windows могут быть стандартные средства для чтения файла из другой ОС? Конечно их нету.

     

    Имелись в виду стандартные средства эмбаркадеро, т.е Delphi/Builder, а не самой windows.

    5 минут назад, ENRGY сказал:

    1. apk - это обычный zip файл.

    Не совсем. Где-то читал, что он может быть шифрован и тогда такой вариант не подойдет.

     

    7 минут назад, ENRGY сказал:

    2. Еще проще

     

    8 минут назад, ENRGY сказал:

    Например чтобы сохранил результат в файл: aapt dump badging myapp.apk > mytextfile.txt

    Я так пробовал с самого начала. Ни ShellExecute ни WinExec у меня не смогли сохранить результат в файл. Все выводилось в консоль. :(

  8. Есть прога(c++) на сервере под Windows. К ней подключаются девайсы под андроид и проверяют обновление некого андроид-приложения. Прога на сервере должна узнать версию лежащего локально apk-файла и сообщить ее девайсу.

    Теоретически можно с помощью aapt получить AndroidManifest.xml файл и вытащить версию от туда. А если ли какие стандартные средства, чтобы узнать версию APK под Windows?

  9. На  Lenovo Yoga было уже предустановлено в систему. Т.е. Lenovo побеспокоилось, чтобы пользователи их девайсов могли запускать не только ява-программы, но и проги с arm-NDK. Как обстоят дела в устройствах других фирм я, к сожалению, не знаю.

  10. Я вот не разобрался как узнать сколько конкретно потребляет моя программа. Какие-то невнятные цифры

    На странице http://developer.android.com/tools/debugging/debugging-memory.html найди крупную строку "Device Monitor". 

    Чуть ниже есть скрин этого монитора. Там выделены кнопки 1 и 2, который нужно нажать и закладка "Heap", на которую нужно стать.

    Как по мне, похожие на правду цифры в мегабайтах. :) Однако, много это или мало, и как вычислить утечки пока не понятно. :) Но все таки уже хоть что-то.

  11. Обнаружил (для себя) интересную стандартную тулзу. Небольшое описание есть здесь: http://developer.android.com/tools/debugging/debugging-memory.html

    Может кому еще пригодится.

     

    Находится она у меня тут:

    C:\Users\Public\Documents\Embarcadero\Studio\15.0\PlatformSDKs\adt-bundle-windows-x86-20131030\sdk\tools\lib\monitor-x86\monitor.exe

    и тут:

    C:\Users\Public\Documents\Embarcadero\Studio\15.0\PlatformSDKs\adt-bundle-windows-x86-20131030\sdk\tools\lib\monitor-x86_64\monitor.exe

     

    Для других версия API и студии, будет аналогичный путь с мелкими отличиями.

     

    Тулза просто так не запустилась. Нужно было в её папке создать еще такое: "jre\bin" и скопировать сюда файл "javaw.exe", который нашел здесь:

    C:\Program Files (x86)\Java\jre1.8.0_60\bin

    64 битная версия нашлась соответственно здесь: C:\Program Files\Java\jre1.8.0_66\bin

     

    С помощью этой тулзы наконец-то увидел используемые моей прогой ресурсы - CPU, mem, threads и т.д.

  12. Не разделять на FMX и VCL - нвизуальгый компонент после установки будет доступен и там и там.

     

    Не хотелось бы так... Хоть код и не зависит от библиотеки (в целом), но все же мелкие различия могут быть, которые нужно за#ifdef-ить. Также Например инклуды для разных платформ/библиотек разные, и либы могут подключаться в зависимости от них.

  13. Всем доброе время суток.

    Делаю "универсальный" компонент для обоих библиотек на C++ Builder. Наследник от TComponent.

    Функционал компонента НЕ зависит от визуальной библиотеки и весь код прописывается в одном файле.

    Попробовал создать 2-а пакаджа. В каждом из них создал пустой компонент, каждый под свою платформу. Имя у компонентов одинаковое. 1-ый пакадж установился, 2-ой нет. Студия сказала, что компонент с таким именем содержится в 1-ом пакадже.

    Вопрос: как правильно создать пакаджи, чтоб компонент был доступен и для VCL-форм и для FMX-форм и имел одинаковое имя?

    Например UniDac компоненты видны для обоих библиотек и имеют одинаковые имена и для VCL и для FMX.

  14. Спасибо за ответ!

    Попробовал "дрыгание". К сожалению костыль не помог.

    Даже выяснилась бОльшая проблема:

    Похоже сама TForm3D не рефрешит то, что на ней.

    Стандартный пример "AnimationDemo3D" из папки "Samples\CPP\FireMonkey Desktop" под OSX не отрисовывает анимацию. Только если подвигать всю форму туда-сюда за пределы экрана, появляются фрагменты кадров анимации.

    PaintRects и Invalidate не помогло.

     

    Похоже вырисовывается серьёзный косяк в XE8.

    Кто-то может запустить-проверить это демо у себя на маке или хакинтоше?

  15. И тишина...

     

    Огромная просьба - если кто-то может делать баг-репорты в Embarcadero, запостите, пожалуйста вышеописанную проблему!!!

    К сожалению с триалом на баг-репорт меня не пускают.

     

    И если у кого есть другая версия OSX - можете подтвердить (или опровергнуть) этот баг?

     

    Всем спасибо!

  16. Здравствуйте всем!

     

    Проверял на OS X - Mountain Lion 10.8.3

     

    После Map/Unmap-обновления картинки, изображение на 3D-форме с TImage3D не обновляется.

     

    Вот простой пример - TestMap.zip - по таймеру заносит шум в TImage3D.Bitmap.

    В XE7 работает и под Win32 и под OSX.

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

     

    BeginUpdate/EndUpdate и Repaint результата не дали.

     

    XE8 Update1 - тоже самое.

     

    Как сие побороть?

     

    (Обычный TImage отрабатывает нормально).

  17. Так. Сорцекопание выявило, что за сортировку 3d-объектов отвечает класс TRenderingCompare и код находится в методе TCustomForm3D.RebuildRenderingList.

    procedure TCustomForm3D.RebuildRenderingList;
    var
      I: Integer;
      CompareFunc: TRenderingCompare;
    begin
      if Assigned(Children) and (Children.Count > 0) and (FUpdating = 0) then
      begin
        if Not Assigned(FRenderingList) then
          FRenderingList := TList<TControl3D>.Create;
        FRenderingList.Clear;
    
        for I := 0 to Children.Count - 1 do
          if (Children[i] is TControl3D) then
            FRenderingList.Add(Children[I] as TControl3D);
    
        CompareFunc := TRenderingCompare.Create;
        try
          FRenderingList.Sort(CompareFunc);
        finally
          CompareFunc.Free;
        end;
      end;
    end;
    

    Никаких условий - просто сортировка без вариантов.

    А вот код, собственно, проверки для сортировки:

    function TRenderingCompare.Compare(const Left, Right: TControl3D): Integer;
    var
      V1, V2: TPoint3D;
    begin
      Result := Integer(Left.GetMaterialForSorting) - Integer(Right.GetMaterialForSorting);
      if (Result = 0) and Left.ZWrite and Right.ZWrite then
      begin
        if (Left.Opacity < 1) and (Right.Opacity >= 1) then
          Result := 1
        else if (Left.Opacity >= 1) and (Right.Opacity < 1) then
          Result := -1
        else if (Left.Context <> nil) and (Right.Context <> nil) then
          begin
            V1 := TPoint3D(Left.AbsolutePosition) - TPoint3D(Left.Context.CurrentCameraMatrix.M[3]);
            V2 := TPoint3D(Right.AbsolutePosition) - TPoint3D(Left.Context.CurrentCameraMatrix.M[3]);
            Result := Trunc(V2.Length - V1.Length);
          end;
      end;
    end;
    

    Как видно если ZWrite = false, 3D-объекты НЕ СОРТИРУЮТСЯ и находятся в порядке создания на форме. Список находится в приватной переменной FRenderingList, к которой мы не можем получить доступ даже сделав наследника от TForm3D.

    Ладно. FRenderingList заполняется из списка TFmxChildrenList.Children, до которого мы можем достучаться. Но его массив Items[] доступен только на чтение. Посему повлиять на его порядок мы тоже не можем.

    Пока что единственный выход, который я нашел - подключать к проекту копию исходника "FMX.Forms3D.pas" и корректировать его под свои нужды. (Под Mac OS X такой финт не работает - берется стандартный "FMX.Forms3D.pas")

    А ведь достаточно было бы сделать RebuildRenderingList виртуальной и хотя-бы в protected секции.

    Ну а лучше, думаю, было бы кустомизировать TRenderingCompare класс.

    Может кто знает лучший вариант?

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