I have a TForm with a TPanel which is linked to the display properties of a TMediaPlayer. By selecting Project -> Resources and Images I was able to insert my video as a resource file, where
filename = abc.avi
type = RCDATA
identifier = Resource_1
unit uForm2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;
type
TForm2 = class(TForm)
MediaPlayer1: TMediaPlayer;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
end;
var
Form2: TForm2;
implementation
uses
ShellAnimations;
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
var
fs: TFileStream;
rs: TResourceStream;
s : String;
m : TMediaPlayer;
begin
rs := TResourceStream.Create(hInstance, 'Resource_1', RT_RCDATA);
s := ExtractFilePath(Application.ExeName) + 'abc.avi';
fs := TFileStream.Create(s, fmCreate);
rs.SaveToStream(fs);
fs.Free;
MediaPlayer1.Close;
MediaPlayer1.FileName := s;
MediaPlayer1.Open;
MediaPlayer1.Play;
MediaPlayer1.Display := Panel1;
end;
When the code is compiled, I get an error:
There is no driver installed in the system
Actually, the "abc.avi" file is 1 MiB. If I use a 1 GiB AVI, I get an error:
The file is being used by another process
How can I play this AVI correctly as a Delphi resource? The AVI in both cases has no sound. If I use a TOpenDialog, the video is played, but I don't want the user to select anything. The video must be embedded in the compiled executable.
______________ Updated code and error messages ______________
TMediaPlayer property:
MediaPlayer1.DeviceType = dtAVIVideo
Reported 4 errors:
1 [dcc32 Error] uForm2.pas(56): E2010 Incompatible types: 'NativeUInt' and 'string'
Line: Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');
2 [dcc32 Error] uForm2.pas(56): E2035 Not enough actual parameters
Line: Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');
3 [dcc32 Error] uForm2.pas(98): E2026 Constant expression expected
Line: ccRES: FOURCC = MAKEFOURCC(Ord('a'), Ord('v'), Ord('i'), Ord(' '));
4 [dcc32 Error] uForm2.pas(146): E2089 Invalid typecast
Line: mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
unit uForm2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;
type
TForm2 = class(TForm)
MediaPlayer1: TMediaPlayer;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses ShellAnimations;
{$R *.dfm}
function MAKEFOURCC(ch0, ch1, ch2, ch3: BYTE): FOURCC;
begin
Result := DWORD(ch0) or (DWORD(ch1) shl 8) or (DWORD(ch2) shl 16) or (DWORD(ch3) shl 24);
end;
function MyResourceIOProc(lpMMIOInfo: PMMIOInfo; uMessage: UINT; lParam1, lParam2: LPARAM): LRESULT; stdcall;
var
Res: TResourceStream;
function GetResourceStream: TResourceStream;
begin
Move(lpMMIOInfo.adwInfo, Result, SizeOf(TResourceStream));
end;
procedure SetResourceStream(Stream: TResourceStream);
begin
Move(Stream, lpMMIOInfo.adwInfo, SizeOf(TResourceStream));
end;
begin
case uMessage of
MMIOM_OPEN: begin
try
Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');
except
SetResourceStream(nil);
Exit(MMIOERR_CANNOTOPEN);
end;
SetResourceStream(Res);
lpMMIOInfo.lDiskOffset := 0;
Exit(MMSYSERR_NOERROR);
end;
MMIOM_CLOSE: begin
Res := GetResourceStream;
SetResourceStream(nil);
Res.Free;
Exit(MMSYSERR_NOERROR);
end;
MMIOM_READ: begin
Res := GetResourceStream;
Move((PByte(Res.Memory) + lpMMIOInfo.lDiskOffset)^, Pointer(lParam1)^, lParam2);
Inc(lpMMIOInfo.lDiskOffset, lParam2);
Exit(lParam2);
end;
MMIOM_SEEK: begin
case lParam2 of
SEEK_SET: begin
lpMMIOInfo.lDiskOffset := lParam1;
end;
SEEK_CUR: begin
Inc(lpMMIOInfo.lDiskOffset, lParam1);
end;
SEEK_END: begin
Res := GetResourceStream;
lpMMIOInfo.lDiskOffset := Res.Size - 1 - lParam1;
end;
end;
Exit(lpMMIOInfo.lDiskOffset);
end;
else
Exit(MMSYSERR_NOERROR);
end;
end;
const
ccRES: FOURCC = MAKEFOURCC(Ord('a'), Ord('v'), Ord('i'), Ord(' '));
procedure TForm2.FormCreate(Sender: TObject);
begin
mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
mmioInstallIOProc(ccRES, nil, MMIO_REMOVEPROC);
end;
procedure TForm2.FormShow(Sender: TObject);
begin
MediaPlayer1.FileName := 'Resource_1.avi+';
MediaPlayer1.Open;
MediaPlayer1.Display:=Panel1;
MediaPlayer1.Play;
end;
end.
Related
I need to play and loop a WAV audio track from resources.
I found an answer to a similar question here: https://stackoverflow.com/a/47960211/19160533
But when I paste it into my code, it says this:
My resources look like this (don't mind the name of the project):
The code I pasted into my project is:
procedure TForm1.FormShow(Sender: TObject);
begin
PlaySound(BG, 0, SND_RESOURCE or SND_ASYNC);
end;
And the whole thing looks like this:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Imaging.pngimage, Vcl.ExtCtrls, Unit2, Unit3, Unit4, Unit5,
Vcl.MPlayer, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
MediaPlayer1: TMediaPlayer;
Button1: TButton;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure MediaPlayer1Enter(Sender: TObject);
procedure MediaPlayer1Notify(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
begin
PlaySound(BG, 0, SND_RESOURCE or SND_ASYNC);
end;
Maybe I need to include some library or something else? I'm new to Delphi.
To use PlaySound() in Delphi, you simply need to add the Winapi.MMSystem unit to your uses clause.
But, since you also have a TMediaPlayer in your project, you could use that instead of PlaySound(), which would have the extra benefit of giving you more control over the playback (pausing/resuming, skipping, etc).
TMediaPlayer does not natively support playing WAV audio from a resource, but it can be done with a little extra coding.
Internally, TMediaPlayer uses MCI via the mciSendCommand() function. According to Microsoft (HOWTO: Use MCI to Play AVI/WAVE Files from Memory), you can setup MCI to play WAV audio from memory (such as a resource) by installing a custom IO callback, and then specifying that callback when opening the player device. Fortunately, the callback is triggered by file extension, hence this approach is compatible with the TMediaPlayer.FileName property.
So, you should be able to write an IO callback function with a custom file extension (for example, .RES for resource), and have that callback load the WAV resource and read its data, and then you would set MediaPlayer1.DeviceType to dtWaveAudio and MediaPlayer1.FileName to a filename ending with the custom extension. The rest is handled by the OS for you, and you can then use MediaPlayer1 to control the playback as needed.
For example (untested, might need some tweaking):
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Imaging.pngimage, Vcl.ExtCtrls, Unit2, Unit3, Unit4, Unit5,
Vcl.MPlayer, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
MediaPlayer1: TMediaPlayer;
Button1: TButton;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure MediaPlayer1Enter(Sender: TObject);
procedure MediaPlayer1Notify(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
Winapi.MMSystem;
{$R *.dfm}
function MAKEFOURCC(ch0, ch1, ch2, ch3: BYTE): FOURCC;
begin
Result := DWORD(ch0) or (DWORD(ch1) shl 8) or (DWORD(ch2) shl 16) or (DWORD(ch3) shl 24);
end;
function MyResourceIOProc(lpMMIOInfo: PMMIOInfo; uMessage: UINT; lParam1, lParam2: LPARAM): LRESULT; stdcall;
var
Res: TResourceStream;
function GetResourceStream: TResourceStream;
begin
Move(lpMMIOInfo.adwInfo, Result, SizeOf(TResourceStream));
end;
procedure SetResourceStream(Stream: TResourceStream);
begin
Move(Stream, lpMMIOInfo.adwInfo, SizeOf(TResourceStream));
end;
begin
case uMessage of
MMIOM_OPEN: begin
try
Res := TResourceStream.Create(HInstance, ChangeFileExt(PChar(lParam1), ''), 'WAVE');
except
SetResourceStream(nil);
Exit(MMIOM_CANNOTOPEN);
end;
SetResourceStream(Res);
lpMMIOInfo.lDiskOffset := 0;
Exit(MMSYSERR_NOERROR);
end;
MMIOM_CLOSE: begin
Res := GetResourceStream;
SetResourceStream(nil);
Res.Free;
Exit(MMSYSERR_NOERROR);
end;
MMIOM_READ: begin
Res := GetResourceStream;
Move((PByte(Res.Memory) + lpMMIOInfo.lDiskOffset)^, Pointer(lParam1)^, lParam2);
Inc(lpMMIOInfo.lDiskOffset, lParam2);
Exit(lParam2);
end;
MMIOM_SEEK: begin
case lParam2 of
SEEK_SET: begin
lpMMIOInfo.lDiskOffset := lParam1;
end;
SEEK_CUR: begin
Inc(lpMMIOInfo.lDiskOffset, lParam1);
end;
SEEK_END: begin
Res := GetResourceStream;
lpMMIOInfo.lDiskOffset := Res.Size - 1 - lParam1;
end;
end;
Exit(lpMMIOInfo.lDiskOffset);
end;
else
Exit(MMSYSERR_NOERROR);
end;
end;
var
ccRES: FOURCC;
procedure TForm1.FormCreate(Sender: TObject);
begin
ccRES := MAKEFOURCC(Ord('R'), Ord('E'), Ord('S'), Ord(' '));
mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
mmioInstallIOProc(ccRES, nil, MMIO_REMOVEPROC);
end;
procedure TForm1.FormShow(Sender: TObject);
begin
MediaPlayer1.FileName := 'BG.RES+';
MediaPlayer1.Open;
MediaPlayer1.Play;
end;
Using Delphi 10.4.1 I tried Custom Managed record management to initialize a record but still get memory leaks.
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, System.IOUtils, System.DateUtils, System.Character,
Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm3 = class(TForm)
Button1: TButton;
RadioGroup1: TRadioGroup;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form3: TForm3;
type
TMyRec = record
DateTime: TDateTime;
v, size: integer;
str: string;
class operator Initialize (out Dest: TMyRec);
end;
TMyREcHolder = class
data: TMyRec;
constructor Create(const e: TMyRec);
end;
TMyList = class(TList)
procedure Clear; override;
end;
implementation
{$R *.dfm}
class operator TmyRec.Initialize (out Dest: TMyRec);
begin
Dest.str := '';
end;
{ TMyREcHolder }
constructor TMyREcHolder.Create(const e: TMyRec);
begin
inherited Create;
data := e;
end;
{ TMyList }
procedure TMyList.Clear;
var
i: integer;
begin
for i := 0 to Count - 1 do
TMyREcHolder(Items[i]).Free;
inherited Clear;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
lst: TMyList;
i: integer;
rec: TMyRec;
FI: TSearchrec;
begin
Initialize(rec);
lst := TMyList.Create;
try
if FindFirst(TPath.Combine('C:\temp', '*.txt'), faAnyFile, FI) = 0 then
begin
repeat
if (FI.FindData.dwFileAttributes and faDirectory = 0) and
(FI.FindData.dwFileAttributes and faArchive = faArchive) then
begin
Application.ProcessMessages;
case RadioGroup1.ItemIndex of
0: Initialize(rec);
1: rec.str := '';
2: fillchar(rec, sizeof(rec), 0);
end;
try
rec.DateTime := FI.TimeStamp;
except
rec.DateTime := EncodeDateDay(1970, 1);
end;
rec.size := FI.size;
rec.str := FI.Name;
lst.Add(TMyREcHolder.Create(rec));
end;
until (FindNext(FI) <> 0);
FindClose(FI);
end;
finally
lst.Free;
end;
end;
end.
The radiogroup offers three items, both 1 and 3 leak memory. Can anyone explain why the Initialize one does? I want a reliable way of clearing a record to help me wean myself off a 20 year fillchar habit.
Hi guys I have an Error that appeared and that I cant get rid off..
I added 2 custom procedures to my delphi code and I read that you can hit crtl+shift+c to autogenerate the functions, which I did.
However my problem now is that I didnt need the autogenerated stuff thats why I deleted it after executing the command. Now my code does not work anymore because of this error I am getting:
E2029 Declaration expected but end of file found
Expected INITIALIZATION but recieved the end of file at line 520(520:1)
How can I fixx my code? Removing or adding a 'end' at the end of the file does not help me. Is there a way to find out where something is missing in my code? (I could post my delphi code but its 500lines long I dont think that makes sense.
Update Code:
unit Benutzerverwaltung_U;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.ComCtrls,
Vcl.StdCtrls,
Vcl.WinXCtrls, Vcl.CheckLst, System.Actions, Vcl.ActnList, Vcl.Menus,
System.StrUtils,
Data.DB, Vcl.Grids, Vcl.DBGrids, Vcl.DBCtrls, FireDAC.Stan.Intf,
FireDAC.Stan.Option, FireDAC.Stan.Param, FireDAC.Stan.Error, FireDAC.DatS,
FireDAC.Phys.Intf, FireDAC.DApt.Intf, FireDAC.Comp.DataSet,
FireDAC.Comp.Client;
type
TForm1 = class(TForm)
other buttons and so on...
procedure SwapValues(var Zahl1, Zahl2: Integer); //new
procedure SelectionSort(Sender: TObject); // new
procedure Button11Click(Sender: TObject); //new
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
workerModel: record
VorName: string[40];
NachName: string[40];
Age: Integer;
Schließen: string[30];
Admin: TToggleSwitchState;
DatenSehen: TToggleSwitchState;
Gender: string[20];
end;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Sonderrechte_U, CheckedItem_U, Unit1, BenutzerEdit_u;
procedure TForm1.SwapValues(var Zahl1, Zahl2: Integer);
var
h: Integer;
begin
h := Zahl1;
Zahl1 := Zahl2;
Zahl2 := h;
end;
procedure TForm1.SelectionSort(Sender: TObject);
var
i, j, min: Integer;
var
sortArray, Data: Array of string;
begin
for i := 1 to Form1.ListBox1.Items.Count - 1 do
// i muss wahrscheinlich 0 sein?
begin
min := i;
for j := i + 1 to Form1.ListBox1.Items.Count do
if (Data[j] < Data[min]) then
min := j;
SwapValues(i, min);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Self);
try
Form2.ShowModal;
finally
Form2.Free;
end;
end;
// more code
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
l: Integer;
t: String;
begin
with ListBox1 do
begin
Canvas.FillRect(Rect);
t := Items[Index];
l := Rect.Right - Canvas.TextWidth(t) - 1;
Canvas.TextOut(l, Rect.Top, t);
end;
end;
procedure TForm1.SearchBox1Change(Sender: TObject);
var
i: Integer;
begin
// SearchBox1.Parent := ListBox1;
ListBox1.Items.BeginUpdate;
try
for i := 0 to ListBox1.Items.Count - 1 do
ListBox1.Selected[i] := ContainsText(ListBox1.Items[i], SearchBox1.Text);
finally
ListBox1.Items.EndUpdate;
end;
// end;
// this is the end of the file
A Delphi unit must end with
end.
(notice the full stop).
I have written a simple loader to install my program and its help file.
unit PSInstaller;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Registry, Vcl.StdCtrls, HTMListB,
HTMLabel, System.Zip;
type
TfmPDSInstaller = class(TForm)
HTMLabel1: THTMLabel;
HTMListBox1: THTMListBox;
btnNext: TButton;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnNextClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
function InstallFile(ResID: integer; pName: String): Boolean;
public
{ Public declarations }
end;
var
fmPDSInstaller: TfmPDSInstaller;
implementation
{$R 'ProtonStudio32.res' 'ProtonStudio32.rc'}
{$R *.dfm}
Var IDEDirectory: String;
Const APP = 100;
HELP = 200;
procedure TfmPDSInstaller.btnNextClick(Sender: TObject);
begin
HTMListBox1.AddItem('Copying Proton Studio to Proton IDE directory',nil);
if InstallFile(APP, 'Studio Application') then begin
HTMListBox1.AddItem('Copying Proton Studio Help to Proton IDE directory',nil);
If InstallFile(HELP, 'Studio Help') then
HTMListBox1.AddItem('Proton Studio Installed', nil);
end;
end;
function TfmPDSInstaller.InstallFile(ResID: integer; pName: String): Boolean;
Var rs: TResourceStream;
Zip: TZipFile;
s: String;
begin
Result := false;
try
Rs := TResourceStream.CreateFromID(HInstance, ResID, RT_RCDATA);
Zip := TZipFile.Create;
try
Zip.Open(Rs,zmRead);
Zip.ExtractAll(IDEDirectory);
finally
Rs.Free;
Zip.Free;
Result := true;
end;
except
on EFOpenError do
s := 'Unable to Open resource ' + pName;
else
s := 'Unable to Copy file from resource ' + pName;
end;
HTMListBox1.AddItem(s, nil);
end;
procedure TfmPDSInstaller.Button1Click(Sender: TObject);
begin
Close;
end;
procedure TfmPDSInstaller.FormCreate(Sender: TObject);
Var Reg: TRegistry;
begin
btnNext.Enabled := false;
Reg := TRegistry.Create;
HTMListBox1.AddItem('Checking for ProtonIDE',nil);
if Reg.OpenKey('Software\MecaniqueUK\ProtonIDE\Install', false) then begin
IDEDirectory := Reg.ReadString('IDE');
Reg.CloseKey;
end;
Reg.Free;
end;
procedure TfmPDSInstaller.FormShow(Sender: TObject);
begin
btnNext.Enabled := false;
if DirectoryExists(IDEDirectory) then begin
HTMListbox1.AddItem('Click Next to install Proton Studio in ' + IDEDirectory, nil);
btnNext.Enabled := true;
end
else
HTMListBox1.AddItem('Proton IDE must be installed first', nil);
end;
end.
I have created a .rc script to load my program and help
#100 RT_RCDATA "D:\Data\Documents\RAD Studio\Projects\ProtonNewIDE\Win32\Debug\ProtonNewIDE.zip"
#200 RT_RCDATA "D:\Data\Documents\RAD Studio\Projects\ProtonNewIDE\Win32\Debug\Proton Studio.zip"
I'm working in Delphi Berlin 10.1, Build resulted in my resource file being generated and I can open it in my Resource Editor but when I try and open the resource:
Rs := TResourceStream.CreateFromID(Application.Handle, ResID, RT_RCDATA);
I get an Address violation. It breaks in System.Classes at this point:
HResInfo := FindResource(Instance, Name, ResType);
and both the Name and ResType are empty.
I would appreciate a pointer to what am I doing wrong?
You are passing a window handle instead of a module handle. Pass HInstance instead, the handle to the module containing this code.
I have a problem when my Form1 appear on body of browser window, simply he disappear when I put focus in my Form and the browser window lose focus. How solved it? Any suggestion will welcome.
See image below:
and here is my complete code:
Unit for enumeration of windows (EnumWindowUtil_.pas):
unit EnumWindowUtil_;
interface
uses
Winapi.Windows,
System.SysUtils,
System.Classes;
type
TWindowList = class(TStringList)
private
FAddClassname: Boolean;
public
procedure EnumChildWindows(handle: HWND);
property AddClassname: Boolean read FAddClassname write FAddClassname;
end;
var
wlistChilds: TWindowList;
implementation
function GetWindowClassName(hwnd: HWND): string;
begin
SetLength(Result, 1024);
GetClassName(hwnd, PChar(Result), Length(Result));
Result := PChar(Result);
end;
procedure EnumWindowCallback(hwnd: HWND; lParam: TWindowList); stdcall;
var
buffer: array[0..255] of char;
texto: string;
begin
if (not IsWindowVisible(hwnd)) then
Exit;
SendMessage(hwnd, $000D, 256, Integer(#buffer));
texto := StrPas(buffer);
texto := texto + ':' + GetWindowClassName(hwnd) + ' - ' + Format('%6.6x', [hwnd]) + '/' + IntToStr(hwnd);
lParam.AddObject(texto, TObject(hwnd));
end;
procedure TWindowList.EnumChildWindows(handle: HWND);
begin
Clear;
if Winapi.Windows.EnumChildWindows(handle, #EnumWindowCallback, Integer(Self)) then;
end;
end.
Here is main unit:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, EnumWindowUtil_,
Vcl.StdCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
linha: string;
implementation
{$R *.dfm}
function GetNavigatorHandle(BASE: HWND): HWND;
var
I: integer;
begin
linha:= '';
Result := 0;
wlistChilds := TWindowList.Create;
wlistChilds.AddClassname := True;
wlistChilds.EnumChildWindows(BASE);
for I := 0 to wlistChilds.Count - 1 do
begin
linha := wlistChilds.Strings[I];
if
(Pos('Chrome_Render',linha)>0)then
begin
Result := StrToInt(copy(linha, pos('/', linha) + 1, Length(linha)));
Break;
end;
end;
FreeAndNil(wlistChilds);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
janela, janelaContainer: HWND;
begin
janela := GetForegroundWindow;
janelaContainer := GetNavigatorHandle(Janela);
if janelaContainer = 0 then
begin
Exit;
end;
Winapi.Windows.SetParent(form1.handle,janelaContainer);
end;
end.