SerhioUser
-
Постов
55 -
Зарегистрирован
-
Посещение
Активность репутации
-
SerhioUser получил реакцию от Rusland в Как получить версию APK-файла под Win32?
Благодарю, Евгений Корепов!
Вот функция 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; } //--------------------------------------------------------------------------- Всем спасибо за участие.
-
SerhioUser получил реакцию от Kitty в Как получить версию APK-файла под Win32?
Благодарю, Евгений Корепов!
Вот функция 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; } //--------------------------------------------------------------------------- Всем спасибо за участие.
-
SerhioUser отреагировална Евгений Корепов в Как получить версию APK-файла под Win32?
Вот так напрямую в память:
function ShellExecuteMy(CommandLine: string; AWorkDir: string = 'C:\') : String; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; StdOutPipeRead, StdOutPipeWrite: THandle; WasOK: Boolean; Buffer: array[0..255] of AnsiChar; BytesRead: Cardinal; WorkDir: string; Handle: Boolean; AOutputLine : String; begin with SA do begin nLength := SizeOf(SA); bInheritHandle := True; lpSecurityDescriptor := nil; end; CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0); try with SI do begin FillChar(SI, SizeOf(SI), 0); cb := SizeOf(SI); dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; wShowWindow := SW_HIDE; // wShowWindow := SW_MINIMIZE; // wShowWindow := SW_NORMAL; hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin hStdOutput := StdOutPipeWrite; hStdError := StdOutPipeWrite; end; WorkDir := AWorkDir; // Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine), Handle := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI); // Result:=PI; CloseHandle(StdOutPipeWrite); finally CloseHandle(StdOutPipeRead); end; if Handle then try repeat // WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil); WasOK := ReadFile(StdOutPipeRead, Buffer, 50, BytesRead, nil); if BytesRead > 0 then begin Buffer[BytesRead] := #0; AOutputLine:=StrOemToAnsi(Buffer); Result :=Result + AOutputLine; end; until not WasOK or (BytesRead = 0); WaitForSingleObject(PI.hProcess, INFINITE); finally CloseHandle(PI.hThread); CloseHandle(PI.hProcess); end; finally CloseHandle(StdOutPipeRead); end; end; Функция читает пайп вывода и помещает в строку.
P.S. uses Winapi.Windows;
-
SerhioUser получил реакцию от Kitty в C++Builder XE 10 & FindStyleResource
Сам столкнулся с этой проблемой. Скомпилировалось так:
TStyleCollectionItem* ci = StyleBook->CurrentItem; Fmx::Types::TFmxObject *style = ci->Style; StyleObject = style->FindStyleResource(AImageName);
-
SerhioUser получил реакцию от Rusland в Z-Order для 3D-объектов с ZWrite=false
Так. Сорцекопание выявило, что за сортировку 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 класс.
Может кто знает лучший вариант?
-
SerhioUser отреагировална Brovin Yaroslav в [TImage] [TPath] Можно ли вывести изображение в виде ромба, круга и тд?
Можно использовать компонент TPath и через кисть заливки (Fill) передать ваш битмап.
Например для звезды:
M227,239 L328,90 L346,250 L201,124 L410,150 L228,238 Заливка картинкой будет такой:
-
SerhioUser отреагировална VladimirS в Дизайн формы
Берешь форму.
Кидаешь TLayout
Он виден на форме (его границы)
Кидаешь TFlowLayout, TFlowLayoutBreak, TGridLayout, TGridPanelLayout - когда они не выделены - они на форме не заметны совершенно.
Если возможно, сделать какую-нить команду типа "показать/скрыть границы контролов"
Или что-то типа предпросмотра, чтобы можно было точно спозиционировать контролы относительно друг друга, а потом посмотреть как это будет выглядеть без сборки и запуска проекта.
-
SerhioUser получил реакцию от Brovin Yaroslav в [OSX] Как изменить прозрачность формы (альфа-канал) под Mac OS?
Ну, как говорится, сам спросил - сам ответил.
Оказывается очень просто: (код на c++)
#include <FMX.Platform.mac.hpp> #include <Macapi.AppKit.hpp> ... NSWindow *Wnd = WindowHandleToPlatform(Form1->Handle)->Wnd; Wnd->setAlphaValue(0.5); // диапазон: 0 .. 1.0 Узнать значение текущего альфа-канала:
float v = Wnd->alphaValue(); -
SerhioUser получил реакцию от Brovin Yaroslav в Как указать целевые платформы для компонента, написанного на C++ Builder?
Спасибо, Brovin Yaroslav.
Эта метода подходит. Мне как раз нужно было указать платформы для всех компонентов в пакете. Их (компонентов) там не много.