忍者ブログ

[PR]

2025年04月29日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

TEdgeBrowserのUserAgentを変更する

2022年02月26日
まずICoreWebView2Settings2を宣言します。
あとはTEdgeBrowserのSettingsInterfaceを使いUserAgentを変更します。
下記は実装例のソースコードです。
 
unit App_WebView2;
interface
uses
  ActiveX, WebView2;
type
  ICoreWebView2Settings2 = interface(ICoreWebView2Settings)
    ['{EE9A0F68-F46C-4E32-AC23-EF8CAC224D2A}']
    function Get_UserAgent(out UserAgent: PWideChar): HResult; stdcall;
    function Set_UserAgent(UserAgent: PWideChar): HResult; stdcall;
  end;
  procedure WebView2_SetUserAgent( SettingsInterface: ICoreWebView2Settings; UserAgent: String );
  function  WebView2_GetUserAgent( SettingsInterface: ICoreWebView2Settings): String;
implementation
procedure WebView2_SetUserAgent( SettingsInterface: ICoreWebView2Settings; UserAgent: String );
begin
  ICoreWebView2Settings2( SettingsInterface ).Set_UserAgent( PWideChar( UserAgent ) );
end;
function  WebView2_GetUserAgent( SettingsInterface: ICoreWebView2Settings): String;
var
  wcUserAgent: PWideChar;
begin
  try
    ICoreWebView2Settings2( SettingsInterface ).Get_UserAgent( wcUserAgent );
    result := wcUserAgent;
  finally
    CoTaskMemFree(wcUserAgent);
  end;
end;

使い方の例はこんな感じです。

unit Unit1;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, WebView2, Winapi.ActiveX, Vcl.Edge;
type
  TForm1 = class(TForm)
    Button1: TButton;
    EdgeBrowser1: TEdgeBrowser;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
uses App_WebView2;
procedure TForm1.Button1Click(Sender: TObject);
begin
  WebView2_SetUserAgent( EdgeBrowser1.SettingsInterface , 'Delphi');
end;

拍手[1回]

PR

自アプリのCPU使用率を調べる

2018年12月10日

unit ProcessCpuUsage;

interface

uses
  Windows, Generics.Collections;

type
  TProcessID = DWORD;

  TSystemTimesRec = record
    KernelTime: TFileTIme;
    UserTime: TFileTIme;
  end;

  TProcessTimesRec = record
    KernelTime: TFileTIme;
    UserTime: TFileTIme;
  end;

  TProcessCpuUsage = class
    LastSystemTimes: TSystemTimesRec;
    LastProcessTimes: TProcessTimesRec;
    ProcessCPUusagePercentage: Double;
  end;

  TProcessCpuUsageList = TObjectDictionary<TProcessID, TProcessCpuUsage>;

var
  LatestProcessCpuUsageCache : TProcessCpuUsageList;
  LastQueryTime              : TDateTime;

  function GetProcessCpuUsageHandle( Handle : THandle ) : Double;
  function GetProcessCpuUsageProcessID( ProcessID: TProcessID ): Double;

implementation

function GetProcessCpuUsageHandle( Handle : THandle ) : Double;
var
  li_ProcID:     DWORD;
begin
  GetWindowThreadProcessId(Handle, @li_ProcID);

  result := GetProcessCpuUsageProcessID(li_ProcID);
end;

function GetProcessCpuUsageProcessID(ProcessID: TProcessID): Double;
  function SubtractFileTime(FileTime1: TFileTIme; FileTime2: TFileTime): TFileTime;
  begin
    Result := TFileTime(Int64(FileTime1) - Int64(FileTime2));
  end;
var
  ProcessCpuUsage  : TProcessCpuUsage;
  ProcessHandle    : THandle;
  SystemTimes      : TSystemTimesRec;
  SystemDiffTimes  : TSystemTimesRec;
  ProcessDiffTimes : TProcessTimesRec;
  ProcessTimes     : TProcessTimesRec;

  SystemTimesIdleTime      : TFileTime;
  ProcessTimesCreationTime : TFileTime;
  ProcessTimesExitTime     : TFileTime;
begin
  Result := 0.0;

  LatestProcessCpuUsageCache.TryGetValue(ProcessID, ProcessCpuUsage);
  if ProcessCpuUsage = nil then begin
    ProcessCpuUsage := TProcessCpuUsage.Create;
    LatestProcessCpuUsageCache.Add(ProcessID, ProcessCpuUsage);
  end;

  ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
  if ProcessHandle <> 0 then begin
    try
      if GetSystemTimes(SystemTimesIdleTime, SystemTimes.KernelTime, SystemTimes.UserTime) then begin

        SystemDiffTimes.KernelTime := SubtractFileTime(SystemTimes.KernelTime, ProcessCpuUsage.LastSystemTimes.KernelTime);
        SystemDiffTimes.UserTime   := SubtractFileTime(SystemTimes.UserTime, ProcessCpuUsage.LastSystemTimes.UserTime);

        ProcessCpuUsage.LastSystemTimes := SystemTimes;

        if GetProcessTimes(ProcessHandle, ProcessTimesCreationTime, ProcessTimesExitTime, ProcessTimes.KernelTime, ProcessTimes.UserTime) then begin

          ProcessDiffTimes.KernelTime := SubtractFileTime(ProcessTimes.KernelTime, ProcessCpuUsage.LastProcessTimes.KernelTime);
          ProcessDiffTimes.UserTime   := SubtractFileTime(ProcessTimes.UserTime, ProcessCpuUsage.LastProcessTimes.UserTime);

          ProcessCpuUsage.LastProcessTimes := ProcessTimes;

          if (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) > 0 then begin
            Result := (Int64(ProcessDiffTimes.KernelTime) + Int64(ProcessDiffTimes.UserTime)) / (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) * 100;
          end;
        end;
      end;
    finally
      CloseHandle(ProcessHandle);
    end;
  end;
end;


initialization
  LatestProcessCpuUsageCache := TProcessCpuUsageList.Create( [ doOwnsValues ] );
finalization
  LatestProcessCpuUsageCache.Free;

end.


使い方の例

uses ProcessCpuUsage;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Label1.Caption := Format('%f', [GetProcessCpuUsageHandle(Handle)] );
end;

拍手[0回]

文字列の暗号化

2014年04月03日
暗号化と復号化のUnit。

unit UEncrypt;

interface

function Decrypt(const S: AnsiString; Key: Word): AnsiString;
function Encrypt(const S: AnsiString; Key: Word): AnsiString;

implementation

const
 C1 = 52845;
 C2 = 22719;

function Decode(const S: AnsiString): AnsiString;
 const
  Map: array[Char] of Byte = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53,
  54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
  3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30,
  31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
  46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0);
var
 I: LongInt;
begin
 case Length(S) of
  2: begin
   I := Map[S[1]] + (Map[S[2]] shl 6);
   SetLength(Result, 1);
   Move(I, Result[1], Length(Result))
  end;
  3:begin
   I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12);
   SetLength(Result, 2);
   Move(I, Result[1], Length(Result))
  end;
  4:begin
   I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) +(Map[S[4]] shl 18);
   SetLength(Result, 3);
   Move(I, Result[1], Length(Result))
  end;
 end;
end;

function PreProcess(const S: AnsiString): AnsiString;
var
 SS: AnsiString;
begin
 SS := S;
 Result := '';
 while SS <> '' do  begin
  Result := Result + Decode(Copy(SS, 1, 4));
  Delete(SS, 1, 4)
 end;
end;

function InternalDecrypt(const S: AnsiString; Key: Word): AnsiString;
var
 I: Word;
 Seed: Word;
begin
 Result := S;
 Seed := Key;
 for I := 1 to Length(Result) do  begin
  Result[I] := Char(Byte(Result[I]) xor (Seed shr 8));
  Seed := (Byte(S[I]) + Seed) * Word(C1) + Word(C2)
 end;
end;

function Decrypt(const S: AnsiString; Key: Word): AnsiString;
begin
 Result := InternalDecrypt(PreProcess(S), Key)
end;

function Encode(const S: AnsiString): AnsiString;
const
 Map: array[0..63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
             'abcdefghijklmnopqrstuvwxyz0123456789+/';
var
 I: LongInt;
begin
 I := 0;
 Move(S[1], I, Length(S));
 case Length(S) of
 1:
  Result := Map[I mod 64] + Map[(I shr 6) mod 64];
 2:
  Result := Map[I mod 64] + Map[(I shr 6) mod 64] +
  Map[(I shr 12) mod 64];
 3:
  Result := Map[I mod 64] + Map[(I shr 6) mod 64] +
  Map[(I shr 12) mod 64] + Map[(I shr 18) mod 64]
 end;
end;

function PostProcess(const S: AnsiString): AnsiString;
var
 SS: AnsiString;
begin
 SS := S;
 Result := '';
 while SS <> '' do  begin
  Result := Result + Encode(Copy(SS, 1, 3));
  Delete(SS, 1, 3)
 end;
end;

function InternalEncrypt(const S: AnsiString; Key: Word): AnsiString;
var
 I: Word;
 Seed: Word;
begin
 Result := S;
 Seed := Key;
 for I := 1 to Length(Result) do  begin
  Result[I] := Char(Byte(Result[I]) xor (Seed shr 8));
  Seed := (Byte(Result[I]) + Seed) * Word(C1) + Word(C2)
 end;
end;

function Encrypt(const S: AnsiString; Key: Word): AnsiString;
begin
 Result := PostProcess(InternalEncrypt(S, Key))
end;

end.



使い方の例

uses
...
UEncrypt;
...
procedure TForm1.Button1Click(Sender: TObject);
const
 SeedKey = 53269;
begin
 Memo2.Text := Encrypt(Memo1.Text,SeedKey);
 Memo3.Text := Decrypt(Memo2.Text,SeedKey);
end;

拍手[14回]

文字列検索

2013年12月18日

文字列の中から特定の文字列を探しだす関数はPosです。
また指定した文字数以降から探す場合はStrUtilsに含まれるPosExです。
一番最後に見つかる位置を知りたい場合は探す文字列と探される側の文字列の両方をReverseStringでひっくり返してPosを使えば調べることが出来ます。
その結果を使いやすいように加工した例が下記になります。

//最後に見つかる文字列位置を調べる
function LastPos(const substr, str: String) : Integer;
begin
  result := Length(str) - Pos( ReverseString(substr) , ReverseString(str) ) - Length(substr) + 2;
end;


//使用例
procedure TForm1.Button1Click(Sender: TObject);
const
  str    = '012345678901234567890123456789';
  substr = '345';
begin
  Edit1.Text := IntToStr(     Pos  (substr , str    ) );
  Edit2.Text := IntToStr(     PosEx(substr , str , 8) );
  Edit3.Text := IntToStr( LastPos  (substr , str    ) );
end;
結果は4,14,24となります。

拍手[9回]

簡単に別スレッドで処理

2013年11月24日

Delphiで別スレッドを使って処理を行う場合TThreadクラスの継承クラスを作成して行うのが一般的ですが、その際必要なパラメーターをいちいちスレッドクラスに渡したりする必要が出てきたりします。
(それが面倒になってグローバル変数を使ってみたり、自身のポインタを渡してみたり^^)
なので簡単に別スレッド処理を使えるように考えてみました。


//簡単スレッドクラス
unit EasyThread;

interface

uses
  Windows, Classes;

type
  TThreadProc = procedure of Object;
  TThreadSync = procedure of Object;

  TEasyThread = class(TObject)
  private type
    TPrivatetThread = class(TThread)
    private
      FThreadProc : TThreadProc;
    public
      constructor Create( ThreadProc : TThreadProc );
    protected
      procedure Execute; override;
    end;
  private
    FThread     : TPrivatetThread;

    function    GetTerminated: Boolean;
  public
    constructor Create( ThreadProc : TThreadProc );
    destructor  Destroy; override;

    procedure   Synchronize( SyncProc : TThreadSync);

    procedure   Terminate;
    procedure   WaitFor;

    property    Terminated : Boolean read GetTerminated;
  end;

implementation

{ TEasyThread }

constructor TEasyThread.Create( ThreadProc : TThreadProc );
begin
  FThread := TPrivatetThread.Create(ThreadProc);
end;

destructor TEasyThread.Destroy;
begin
  if Assigned(FThread) then FThread.Free;

  inherited;
end;

function TEasyThread.GetTerminated: Boolean;
begin
  result := FThread.Terminated;
end;

procedure TEasyThread.Terminate;
begin
   if Assigned(FThread) then FThread.Terminate;
end;

procedure TEasyThread.WaitFor;
begin
  try
     if Assigned(FThread) then FThread.WaitFor;
  except end;
end;

procedure TEasyThread.Synchronize(SyncProc: TThreadSync);
begin
   if Assigned(FThread) then FThread.Synchronize(SyncProc);
end;

{ TEasyThread.TPrivatethread }

constructor TEasyThread.TPrivatetThread.Create(ThreadProc: TThreadProc);
begin
  inherited Create(False);

  FThreadProc := ThreadProc;
end;

procedure TEasyThread.TPrivatetThread.Execute;
begin
  if Assigned(FThreadProc) then FThreadProc;
end;

end.

・簡単スレッドクラスを使う例
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, EasyThread;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Count : Integer;
    ET    : TEasyThread;
  public
    procedure ThreadProcedure;  //別スレッドから呼ばれる
    procedure VCL;  //別スレッドからVCLにアクセスする場合に使う
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;

  if not Assigned(ET) then ET := TEasyThread.Create(ThreadProcedure);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(ET) then ET.Free;
end;

procedure TForm1.ThreadProcedure;
begin
   //別スレッドから呼ばれる関数内でループ処理を行う場合は、かならずTerminated変数を監視する 
  while not ET.Terminated do begin  
  
    Inc(Count);

    //VCLを使う場合はSynchronizeから呼び出す
    ET.Synchronize(VCL);

    Sleep(1);

    if Count = 3000 then Break;
  end;
end;

procedure TForm1.VCL;
begin
  Label1.Caption := IntToStr(Count);
end;

拍手[5回]

 | HOME | 次のページ »