Avatar billede whynot Nybegynder
24. maj 2004 - 22:51 Der er 17 kommentarer og
1 løsning

opdatere tekstboks på form vha. API

Jeg har en form1 som creater en form2 hver gang man trykker på knap1.... se koden nedenfor.

procedure TForm1.Button1Click(Sender: TObject);
var
  child: TForm2;
begin
  inc(i);

  child := TForm2.Create(Application);
  with child do
  begin
    child.Edit1.Text := inttostr(i);
    Show;
  end;
end;

hertil er alting godt...

men nu vil jeg gerne opdatere edit1.text på form2... MEN hvordan gør man det? jeg har prøvet at finde ud af hvordan jeg tilgår vha. API.. og jeg har indtil videre fundet ud af hvordan man finder et vindues handle/Hwnd og sætter det vindue i fokus vha. SetForegroundWindow(myhandle);

Men på form2 er der en tekstboks som hedder edit1.. denne vil jeg gerne kunne skrive i fra f.eks. form1 men sådan at man rammer det korrekte vindue/handle... jeg forestiller mig noget i retningen af:

var
  myform: Tform;
  myhandle: Hwnd;
begin
  myform := find_vindue_ud_fra_handle(myhandle);
  myform.edit1.text := 'hyggehejsa';
end;


...er der nogen som kan hjælpe mig?
Avatar billede nca Juniormester
25. maj 2004 - 08:07 #1
Du kan skrive til edit1 på form2 på denne måde:
form2.edit1.text:='Dette er en test';

Husk at tilføje Form2 under Uses i Form1
Avatar billede whynot Nybegynder
25. maj 2004 - 08:22 #2
øhm nej det kan jeg ikke.. fordi form2 ikke "hedder" form2.. den er skabt som en klon af form2 - men den er ikke form2. Den er createt vha. child := TForm2.Create(Application); og derved er den nye form som en form2 - men den kaldes ikke form2 af windows.

SPørgsmålet er hvordan tilgår jeg form2 når jeg har formens handle/Hwnd?

...men ellers tak for forsøget :)
Avatar billede nop Nybegynder
25. maj 2004 - 10:01 #3
Men nca har ret men du er nød til at flytte din child var ud i form1, det du har lavet er en fejl da child bliver sluppet af button1click og du får derfor aldrig frigivet form2. Og hvad hvis du trykker to gange? (men jeg går udfra at det er et eksempel du kommer med).
Du behøves aldrig søge efter et programs egne forme, dem kreerer programmet jo selv.
Avatar billede whynot Nybegynder
25. maj 2004 - 10:56 #4
øhmm nej det var faktisk ikke blot et eksempel.. det er sådan min kode er.. I kan se mine to units her:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, Grids, DBGrids, ShellApi, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Panel1: TPanel;
    Button4: TButton;
    Memoresult: TMemo;
    Panel2: TPanel;
    Button3: TButton;
    Edit2: TEdit;
    ListBox1: TListBox;
    Button5: TButton;
    Button6: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2;

var
  i: integer;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  form2.show;
  form2.edit1.text := form1.Edit1.Text; ;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  child: TForm2;
begin
  inc(i);

  child := TForm2.Create(Application);
  with child do
  begin
    //child.Label_datofil.Caption := opret_dato;
    child.Caption := inttostr(i);
    child.Edit1.Text := inttostr(i);
    Show;
  end;
end;


procedure TForm1.Button3Click(Sender: TObject);
var
  myhandle: Hwnd;
  WindowText: array[0..255] of char; // holds the text of the window
  tempform: Tform;
begin
//form1.ListBox1.Items.
  myHandle := FindWindow(nil, PChar(edit2.Text));
//myHandle:=FindWindow(nil,'Form1');// form1 er caption

  if myHandle <> 0 then
  begin
  // ShowWindow(myhandle, SW_MAXIMIZE);
  // ShowWindow(myhandle, SW_NORMAL); //SW_HIDE, SW_NORMAL, SW_SHOW
    SetForegroundWindow(myhandle);

    tempform.ActiveMDIChild.fo(myhandle).edit1.text := 'hejsa';
//    tempform.Edit1.text := 'hejsa';
    setparent

    GetWindowText(myHandle, WindowText, 255); // Get the text from the window
    Form1.ListBox1.Items.Add(WindowText); //Display it in the listbox
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  pHandle: HWND;
begin
  ShellExecute(Handle, 'open', PChar('C:\windows\NotePad.exe'), '', '', sw_ShowNormal);
  Sleep(500);
  pHandle := FindWindowEx(FindWindow('notepad', nil), 0, 'Edit', nil);
  SendMessage(pHandle, WM_SETTEXT, 0, integer(MemoResult.Text));
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  myhandle: Hwnd;
begin
  if form1.listbox1.itemindex <> -1 then
  begin
    myHandle := FindWindow(nil, PChar(form1.listbox1.Items.strings[form1.listbox1.itemindex]));
    if myHandle <> 0 then
    begin
      ShowWindow(myhandle, SW_SHOWNORMAL);
      SetForegroundWindow(myhandle);
      form1.ListBox1.Items.Delete(form1.ListBox1.ItemIndex);
    end;
  end;
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  myhandle: Hwnd;
begin
  if form1.listbox1.itemindex <> -1 then
  begin
    myHandle := FindWindow(nil, PChar(form1.listbox1.Items.strings[form1.listbox1.itemindex]));
    if myHandle <> 0 then
    begin
      ShowWindow(myhandle, SW_SHOWNORMAL);
      SetForegroundWindow(myhandle);
      form1.ListBox1.Items.Delete(form1.ListBox1.ItemIndex);
    end;
  end;
end;

end.

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DB;

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Button3: TButton;
    procedure Button3Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.Button3Click(Sender: TObject);
var
  WindowText: array[0..255] of char; // holds the text of the window
begin
  GetWindowText(self.Handle, WindowText, 255); // Get the text from the window
  Form1.ListBox1.Items.Add(WindowText); //Display it in the listbox
  ShowWindow(self.Handle, SW_HIDE);
end;

procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  WindowText: array[0..255] of char; // holds the text of the window
begin
  if MessageDlg('Vil du "hide" formen i stedet for at lukke?', mtConfirmation,
    [mbYes, mbNo], 0) = mrYes then
  begin
    CanClose := False;

    GetWindowText(self.Handle, WindowText, 255); // Get the text from the window
    Form1.ListBox1.Items.Add(WindowText); //Display it in the listbox
    ShowWindow(self.Handle, SW_HIDE);
  end
  else
    DestroyWindow(self.Handle);
end;

end.
Avatar billede whynot Nybegynder
25. maj 2004 - 10:58 #5
som i kan se af koden er det "procedure TForm1.Button3Click(Sender: TObject);" hvor jeg prøver at opdatere min nye forms tekstboks til "hejsa".. dette gør jeg ved at finde det vindue med caption=form1.edit2.text.. for derefter at bruge dette som handle som referent.. men det er denne ting som jeg ikke kan gennemskue hvordan jeg skal gøre.


.... er jeg helt galt i byen.. eller hva' ?
Avatar billede nop Nybegynder
25. maj 2004 - 10:59 #6
og du er ikke med på hvad jeg mener med at flytte din var som holder formen?
Avatar billede nop Nybegynder
25. maj 2004 - 11:04 #7
Det kan være jeg/vi ikke lige forstod det med listboxen men du skal stadig flytte din child op efter, og sikkert i et array eller til objected til linjerne.
Avatar billede whynot Nybegynder
25. maj 2004 - 11:10 #8
hmmm jeg er vist ikke helt med omkring det med at "flytte min var som holder formen".. .. hmmm
Avatar billede whynot Nybegynder
25. maj 2004 - 11:11 #9
..synes måske det lyder lidt smart at holde styr på mine forms vha. et array.. men er det ikke et kæmpe mas at holde styr på?
Avatar billede nop Nybegynder
25. maj 2004 - 11:23 #10
procedure TForm1.Button2Click(Sender: TObject);
var
  child: TForm2;  //den her holder faktisk din "eneste" ref til formen, ok?
begin
  inc(i);

  child := TForm2.Create(Application); //her returneres en pointer til formen...
  with child do
  begin
    //child.Label_datofil.Caption := opret_dato;
    child.Caption := inttostr(i);
    child.Edit1.Text := inttostr(i);
    Show;
  end;
end;

variablen fjernes fra delphi ved exit fra din proc, ikke også?

Istedet for så skal du gemme værdien, og da du allerede vil have en linje i en listbox til hver form (ikke også?) så kan du jo lige så godt gemme den i listbox.items.objects
  • som næsten er beregnet på det, så undgår du det "besværlige array".
  • Du vil så trykke på but2 (=opret en form):

    procedure TForm1.Button2Click(Sender: TObject);
    var
      child: TForm2;
    begin
      inc(i);
      child := TForm2.Create(Application); //her returneres en pointer til formen...
      with child do
      begin
        //child.Label_datofil.Caption := opret_dato;
        child.Caption := inttostr(i);
        child.Edit1.Text := inttostr(i);
        Show;
      end;
      listbox1.add(child.caption,child); //tror det er sådan her
                        //logisk er det korrekt ihvertilfælde
    end;

    Ellers har jeg lidt svært ved se hvad du vil med programmet, skal man ikke kunne trykke på linjerne i listbox'en sådan at formen der hører til vises, og evt osse kunne slette en linje i listen, så skal formen jo frigives.
    Og ved luk så skal listen løbes igennem og formene frigives.
    Avatar billede whynot Nybegynder
    25. maj 2004 - 11:41 #11
    programmet er en prototype hvor jeg afprøver nogle ting før de ryger over i mit "rigtige" program..

    ok.. nu kan jeg gemme en form i listboksen - men hvordan pokker for jeg den så ud igen?

    det må være noget i retningen af:

    var
    child: TForm2;
    begin
    child:=form1.ListBox1.Items.Objects[form1.listbox1.itemindex];

    eller? fordi den giver en fejl med at et objekt ikke er det samme som Tform2 - og det har den jo ret i ;)
    Avatar billede nop Nybegynder
    25. maj 2004 - 11:46 #12
    prøv:
    child:=form1.ListBox1.Items.Objects[form1.listbox1.itemindex] as Tform2;
    Avatar billede whynot Nybegynder
    25. maj 2004 - 12:35 #13
    jamen dog.. det virker :)

    ... men nu har jeg en listboks med henvisninger.. hvordan rydder jeg op i den når brugen blot lukker den enkelte form ned?

    Jeg har lavet følgende procedure:

    procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
      if MessageDlg('Vil du lukke formen ned nu?', mtConfirmation,
        [mbYes, mbNo], 0) = mrYes then
      begin
        CanClose := True;
        self.Free;
      end
      else
    CanClose := false;
    end;

    Men det fjerner jo ikke henvisningen i listboksen.. eller hvad?
    Avatar billede nop Nybegynder
    25. maj 2004 - 12:43 #14
    ca:

    for i:=0 to listbox1.items.count
      listbox1.items.objects[i] as Tform2.free;

    --nop
    Avatar billede nop Nybegynder
    25. maj 2004 - 12:44 #15
    :) det rydder alle op, men fremgangs metoden er ens.
    Avatar billede whynot Nybegynder
    25. maj 2004 - 12:46 #16
    hey.. okey.. jeg har fundet ud af det..

    .. det er en klyt metode men det virker!

        for i := 0 to form1.ListBox1.Items.Count - 1 do
          if form1.ListBox1.Items[i] = self.Caption then
            form1.ListBox1.Items.Delete(i);
    Avatar billede whynot Nybegynder
    25. maj 2004 - 12:47 #17
    hey.. fedt nok... !.. så tror jeg at vi har den :)

    Mange tak for hjælpen.
    Avatar billede nop Nybegynder
    25. maj 2004 - 12:48 #18
    den er ok men måske skulle du sammenligne på Tform2 objected, så kan dine captions være internationale (!!!).
    Avatar billede Ny bruger Nybegynder

    Din løsning...

    Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

    Loading billede Opret Preview
    Kategori
    Kurser inden for grundlæggende programmering

    Log ind eller opret profil

    Hov!

    For at kunne deltage på Computerworld Eksperten skal du være logget ind.

    Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

    Du kan også logge ind via nedenstående tjenester