Wywołanie funkcji i oczekiwanie na wybór. Własny MessageBox.

0

Witam.
Mam pytanie.
Czy możliwe jest napisanie funkcji która wywoła formularz i będzie oczekiwała na wybór określonego parametru a po wyborze zamknięcie formularza i zwrócenie przez te funkcje parametru wyboru. Na początku wydawało się to proste ale nie bardzo wiem jak oczekiwać na kliknięcie przycisku i zwrócić parametr wyboru. Pytam o to bo często będę wywoływał funkcje rezultat będzie przypisywany za każdym razem do innej zmiennej. Pomoże ktoś? Szukam od 2 dni i niestety nic nie znalazłem.

0

ShowModal i (chyba) ModalResult

1

można, jak najbardziej ..

unit logowanie;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  inifiles, Dialogs, WideStrings, DB, SqlExpr, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button1: TButton;
    Button2: TButton;
    
    procedure Button1Click(Sender: TObject); (OK)
    procedure Button2Click(Sender: TObject); (anuluj logowanie)
  private
    { Private declarations }
  public
     jakas_wlasnosc:string;
    { Public declarations }
  end;

function zaloguj(var polaczenie: TSQLConnection;   Sender: tcomponent): boolean;

var
  Form1: TForm1;

implementation

{$R *.dfm}
{ TForm1 }

function zaloguj(var polaczenie: TSQLConnection;   Sender: tcomponent): boolean;
label poczatek;
var
  ti: tinifile;
  password, user, baza: string;
  sukces: boolean;
  okno_logowania: TForm1;
  cos_tam:string;
begin
poczatek :
  if polaczenie.Connected then
  begin
    result := true;
    exit;
  end;
  ti := tinifile.Create(extractfilepath(application.ExeName) + '\config.ini');
  password := ti.ReadString('logowanie', 'password', '');
  user := ti.ReadString('logowanie', 'user', '');
  baza := ti.ReadString('logowanie', 'baza', '');
  ti.Free;
  polaczenie.Params.Values['user_name'] := user;
  polaczenie.Params.Values['password'] := password;
  polaczenie.Params.Values['database'] := baza;
  try
    polaczenie.Open;
    sukces := true;
  except
    sukces := false;
  end;

  if sukces then
    goto poczatek;

/// tutaj utworzenie formy i odczyt wyniku w postaci INTEGER
/// można dodać do fomy dodatkową własność dowolnego typu  np "jakas_wlasnosc", a  po  zamknięciu formy odczytać jego zawartośc, ... 

  okno_logowania := TForm1.Create(Sender);
  okno_logowania.Edit1.text := baza;
  okno_logowania.Edit2.text := user;
  okno_logowania.Edit3.text := password;

  if okno_logowania.ShowModal = 27 then
  begin
    okno_logowania.free;
    result := false;
    exit;
  end;

  /// odczyt dodatkowej wlasnosci formy "okno_logowania"
 /// po zamknieciu formy 
  cos_tam:=okno_logowania.jakas_wlasnosc;

  ti := tinifile.Create(extractfilepath(application.ExeName) + '\config.ini');
  ti.writeString('logowanie', 'baza', okno_logowania.Edit1.text);
  ti.writeString('logowanie', 'user', okno_logowania.Edit2.text);
  ti.writeString('logowanie', 'password', okno_logowania.Edit3.text);
  ti.Free;
  okno_logowania.Free;
  goto poczatek;

end;

procedure TForm1.Button1Click(Sender: TObject);  (OK)
begin
  self.ModalResult := 13;
end;

procedure TForm1.Button2Click(Sender: TObject);  (anuluj)
begin
  self.ModalResult := 27;
end;

end.
0

Poprawiłem mały błąd i działa choć jak zamykam to wyskakuje mi błąd - powiedz proszę jak wywołujesz funkcje? co wstawiasz w miejsce sender?

1

Jeżeli chcesz zrobić custom MessageBox'a to pod VCL jest funkcja CreateMessageDialog. Przykład poniżej:

//...
procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.Title := MainForm.Caption;
  MainForm.Position := poScreenCenter;
  MainForm.ActiveControl := ShowMsgDlgButton;
end;

procedure TMainForm.FormActivate(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TMainForm.CBXOnClick(Sender : TObject);
begin
  with Sender as TCheckBox do
  begin
    if Checked then
    begin
      ShowMessage('Zaznaczyłeś');
    end
    else
    begin
      ShowMessage('Odznaczyłeś');
    end;
  end;
end;

procedure TMainForm.ShowMsgDlgButtonClick(Sender: TObject);
var
  Dlg : TForm;
  CBX : TCheckBox;
begin
  Dlg := CreateMessageDialog('Czy na pewno chcesz zamknąć program?',
  mtConfirmation, [mbYes, mbNo]);
  Dlg.Caption := Application.Title;
  Dlg.BorderIcons := [];
  Dlg.Height := 130;
  Dlg.ActiveControl := TButton(Dlg.FindComponent('Yes'));
  TImage(Dlg.FindComponent('Image')).Picture.Assign(Application.Icon);
  TButton(Dlg.FindComponent('Yes')).Caption := 'Tak';
  TButton(Dlg.FindComponent('No')).Caption := 'Nie';
  TButton(Dlg.FindComponent('Yes')).Top := 70;
  TButton(Dlg.FindComponent('No')).Top := 70;
  CBX := TCheckBox.Create(Dlg);
  CBX.Parent := Dlg;
  CBX.Caption := 'Zawsze pytaj';
  CBX.Left := (Dlg.Width - CBX.Width) div 2;
  CBX.Top := 40;
  CBX.Checked := False;
  CBX.OnClick := CBXOnClick;
  Dlg.ShowModal;
  case Dlg.ModalResult of
    mrYes : begin
      Caption := 'Tak';
    end;
    mrNo : begin
      Caption := 'NIE';
    end;
  end;
  if CBX.Checked then
  begin
    Caption := Caption + #32 + '- Zaznaczony';
  end
  else
  begin
    Caption := Caption + #32 + '- Odznaczony';
  end;
end;
//...

Jednak jeżeli korzysta się ze starszej wersji Delphi, jak na przykład 7, pod nowszym Windowsem to okno to będzie - o ile się nie myle - w stylu starego Windowsa. Jest też inny sposób pokazany na: http://www.howtodothings.com/computers/a975-how-to-create-custom-inputquerymessagebox-etc-without-pain.html dla standardowych okienek. Poza podmianą tekstów na przyciskach można przez funckje WinAPI na przykład rozszerzyć te okienko, a także na przykład przechwycić i zmodyfikować procedurę obsługi komunikatów przez SetWindowLong z parametrem GWL_WNDPROC. Można wtedy dodać przez CreateWindow jakiegoś checkboxa lub inny komponent z okien dialogowych WinAPI i w ten sposób kombinowac. Więcej znajdziesz szukając w google i oczywiście warto zajrzeć na MSDN.

0

Grzegorz_so:
dam przykład
function jakasfunkcja(parametry):tedit;
edit1:=jakasfunkcja(..);
błąd mam jak
result.caption:='cos';
nie wiem czy dobrze że zwracam jako TEdit.

W sumie funkcja zwracać ma mi dwa parametry - string i integer tylko nie bardzo wiedziałem jak najprościej zwrócić 2 parametry:(

0

zdefiniuj sobie nowy typ typu record

type
rezultat_funkcji = record
wynik_string:string;
wynik_integer: integer
end;

i samą fuknkcję jako :
moja_funkcja(lista parametrow ....): rezultat_funkcji:

function moja_funkcja(lista parametrow ....): rezultat_funkcji:
var wynik: rezultat_funkcji;
begin
...
....
///
wynik.wynik_string:=cos_tam1;
wynik.wynik_integer:=cos_tam2;
result:=wynik
////lub
result.wynik_string := cos_tam1;
result.wynik_integer:=cos_tam2
end

0

Ja mam troszkę inny sposób na tworzenie własnego okna dialogowego (opracowany na bazie artykułu z sieci, ale nie mam pojęcia kiedy i skąd go pobrałem...):

  1. Deklaracja typów, kod metod:
unit SaveCode;

//...

type
  //klasa formularza
  TSaveForm = class(TForm)
    //zawartość formularza - komponenty i ich procedury
  private
    sFileName: String;  //potrzebne do dialogu
  end;

  //klasa obiektu wywołującego powyższy formularz
  TSaveDlg = class(TObject)
  private
    fSaveForm: TSaveForm;
    sFileName: String;
    procedure DlgFormClose(Sender: TObject; var Action: TCloseAction);
  public
    constructor Create;
    function Execute: Boolean;
  published
    property FileName: String read sFileName write sFileName;
  end;

//...

//metody obiektu wywołującego powyższy formularz
constructor TSaveDlg.Create;
begin
  inherited Create;

  fSaveForm := nil;
  sFileName := '';
end;

procedure TSaveDlg.DlgFormClose(Sender: TObject; var Action: TCloseAction);
begin
  //tu wklejamy cały kod jaki zapisaliśmy w TSaveForm.FormClose
  //wszystko co chccemy zrobić podczas zamykania formularza
  //procedure TSaveForm.FormClose usuwamy z modułu

  Action := caFree;
end;

function TSaveDlg.Execute: Boolean;
begin
  if not Assigned(fSaveForm) then
    fSaveForm := TSaveForm.Create(Application);

  fSaveForm.OnClose := DlgFormClose;

  Result := Boolean(fSaveForm.ShowModal);

  if sFileName = '' then
    Result := False;
end;

//...
  1. Przykład użycia obiektu wywołującego formularz
//...

interface

uses SaveCode;

//...

procedure TMainForm.btnSaveClick(Sender: TObject);
var
  SaveDlg: TSaveDlg
begin
  SaveDlg := TSaveDlg.Create;

  try
    if SaveDlg.Execute then
      //operacje wykonywane jeżeli został wciśnięty odpowiedni przycisk
    else
      //operacje wykonywane jeżeli formularz został zamknięty X lub przyciskiem Anuluj
  finally
    FreeAndNil(SaveDlg);
  end;
end;

Gdyby trzeba było coś wytłumaczyć - służę pomocą :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1