Problem mit vfw

danny61
Beiträge: 94
Registriert: So 5. Nov 2006, 18:40
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Berlin

Beitrag von danny61 »

Ich habe jetzt im Constructor
Parent:=(aOwner as TWinControl);
geschrieben und so funktioniert es.

Was ist denn der Unterschied zwischen Owner und Parent ?

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Christian hat geschrieben:@theo lies dir doch den thread mal von anfang an durch und stell nich die selben fragen wie ich nochma :) der fehler tritt tief im lcl code auf eigentlich müsste es so funktionieren wie ers macht da hatter schon recht


Ach was. Im Konstruktor gibt's noch keinen Parent.
Deshalb wird das Panel ja auch nicht angezeigt, bevor Parent gesetzt ist.
procedure CreateVWnd; ist ne einfache Methode, die nicht eine Methode von TWincontrol überschreibt. (Heisst nicht CreateWnd !!! und ist auch nicht overridden).

Der langen Rede kurzer Sinn: Im Konstruktor gibt's noch kein Winhandle erst nach dem setzen von Parent.
Deshalb da die Zugriffsverletzung, weil Handle noch nicht gültig ist.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

danny61 hat geschrieben:Ich habe jetzt im Constructor
Parent:=(aOwner as TWinControl);
geschrieben und so funktioniert es.

Was ist denn der Unterschied zwischen Owner und Parent ?


Sag ich doch! ;-)
Einfach gesagt: Owner ist die Komponente welche die Kindkomponente freigibt.
Parent ist das Elternfenster innerhalb dessen die Kindkomponente angezeigt wird.
Du kannst locker Owner als Form1 und Parent als Panel1 setzen.

Capito?

danny61
Beiträge: 94
Registriert: So 5. Nov 2006, 18:40
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Berlin

Beitrag von danny61 »

Das heisst Owner müßte im Prinzip immer mein Form sein.
Wenn ich das Control innerhalb eines Panels anzeigen will, würde mein Constructor nicht mehr funktionieren.
Ich müßte den Parent manuell setzen und könnte somit mein CapWnd nicht im Constructor erzeugen, sondern müßte eine Methode dafür schreiben die erst aufgerufen werden darf, wenn der Parent gesetzt wurde, richtig ?

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

danny61 hat geschrieben:Das heisst Owner müßte im Prinzip immer mein Form sein.
Wenn ich das Control innerhalb eines Panels anzeigen will, würde mein Constructor nicht mehr funktionieren.
Ich müßte den Parent manuell setzen und könnte somit mein CapWnd nicht im Constructor erzeugen, sondern müßte eine Methode dafür schreiben die erst aufgerufen werden darf, wenn der Parent gesetzt wurde, richtig ?


Easy! Soviel ich weiss, spielt es keine grosse Rolle welche Komponente der Owner ist.
Also Panel geht auch als Owner.

Ich Prinzip kannst du auch nil als Owner übergeben, nur musst du dann die Komponente selber freigeben.

Also wenn du keine Akrobatik damit machst, passt das schon.
Wenn du allerdings das Control "re-parentest", also einen neuen Parent während der Laufzeit setzt, würde ich anders vorgehen.
Dann würde ich z.B. TControl.SetParent überschreiben, vielleicht sogar TWinControl.CreateWnd

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Bzw. um allfällige Stildiskussionen von Christian und Schnulli ;-) vorwegzunehmen: Mach's doch gleich richtig:

Code: Alles auswählen

Type
 
  { TVideoCap }
 
  TVideoCap = Class(TPanel)
  private
   FCapHandle : HWND;
  protected
    procedure CreateWnd; override;
 
  public
 
  end;
 
var
  Form1: TForm1;
 
implementation
 
{ TVideoCap }
 
procedure TVideoCap.CreateWnd;
begin
  inherited CreateWnd;
  ShowMessage(Inttostr(Handle));
  FCapHandle:=capCreateCaptureWindow('Video Capture',WS_CHILD or WS_VISIBLE  or WS_CLIPCHILDREN or WS_CLIPSIBLINGS,0,0,Width,Height,Handle,1);
end;


Natürlich musst du jetzt den Parent wieder wie normal setzen. z.B:

Code: Alles auswählen

VC:=TVideoCap.Create(self);
VC.Parent:=Panel1;


Achte auch noch darauf, dass die Dimensionen stimmen!
Wenn du nachher Width, oder Height setzt muss das CaptureWindow wahrscheinlich angepasst werden.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

Hallo,

ich glaube Theo ist am richtigen Weg, soweit ich die Komponenten kenne, muss ich sagen , der Aufruf

Code: Alles auswählen

procedure TVideoCap.CreateVWnd;
begin
   FCapHandle:=capCreateCaptureWindow('Video Capture',WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS,0,0,Width,Height,Handle,1);
end;
 
constructor TVideoCap.Create(aOwner:TComponent);
begin
  inherited create(aOwner);
  CreateVWnd;
end;

im Constructor muss fehlschlagen, denn das Panel hat zu diesem Zeitpunkt ja noch keine Ahnung wer sein Parent und somit über das Handle des Parent.

The capCreateCaptureWindow function creates a capture window.

HWND VFWAPI capCreateCaptureWindow(
LPCSTR lpszWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWnd,
int nID
);

Parameters

lpszWindowName

Null-terminated string containing the name used for the capture window.

dwStyle

Window styles used for the capture window. Window styles are described with the CreateWindowEx function.

x

The x-coordinate of the upper left corner of the capture window.

y

The y-coordinate of the upper left corner of the capture window.

nWidth

Width of the capture window.

nHeight

Height of the capture window.

hWnd

Handle to the parent window.

nID

Window identifier.

Return Values

Returns a handle of the capture window if successful or NULL otherwise.

Requirements

Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and later.
Header: Declared in Vfw.h.
Library: Use Vfw32.lib.
Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP.


Dieses wird ja erst später, bzw. explizit von programmier zugewiesen (wenn nicht durch das drag&drop automatisiert)

Wenn man die TPanel Komponenete in die Tiefe verfolgt son findet man
Method: TWinControl.HandleNeeded

in der der :!: Parent :!: um das Handle gefragt wird, wenn der parent zugewiesen wurde !

SOmit würde ich sagen, der Aufruf hat im Constructor nichts verloren, sondern sollte erst beim Anfordern des vfw-Handels oder ähnlicherzeugt werden und dort prüfe zuerst, ob das Panel alle nötigen Parameter bereitstellt, ansonsten einen exception schmeissen, das das Panel noch keinen Parent hat.

Andi
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

af0815 hat geschrieben:
SOmit würde ich sagen, der Aufruf hat im Constructor nichts verloren, sondern sollte erst beim Anfordern des vfw-Handels oder ähnlicherzeugt werden und dort prüfe zuerst, ob das Panel alle nötigen Parameter bereitstellt, ansonsten einen exception schmeissen, das das Panel noch keinen Parent hat.

Andi


Das geht natürlich auch.
Aber wie gesagt: Resize berücksichtigen! Eventuell musst du das alte Handle auch noch freigeben, damit's mit dem Memory passt. Bin nicht mehr so fit auf Winapi ;-)

Antworten