Einzelnen Beitrag anzeigen

FarAndBeyond
(Gast)

n/a Beiträge
 
#1

NotifyWindow, dynamisches Fenster in nur einer Prozedur inklusive Events und AA

  Alt 27. Jul 2015, 19:29
Hi,
Ich wollte ein Nachrichtenfenster bzw. Errorfenster bauen, dass man einfach überall verwenden kann und nur eine Prozedur in ein Projekt kopieren muss. Ich hab' mal 'nen Post gelesen von Mirage228 und so 'was hatte ich zuvor noch nie gesehen.

Das Fenster sollte folgende Eigenschaften haben:
1) Nur schließbar mit OK-Taste
2) Topmost
3) Modal
4) Und alles was man braucht (Funktionen, Events, Antialiasing) in einer einzigen Prozedur (praktisch und portable)

Dieser QuellCode lässt sich compilieren unter D7. (Nicht auf das ExceptionHandling achten, damit fang ich gerade erst an..)

Das CloseQueryEvent scheint auch zu funktionieren, da das Fenster nicht mit Alt+F4 geschlossen werden kann.
Das KeyDownEvent schein zumindest teilweise zu funktionieren, da ich erst die AccessViolation bekomme bei der richtigen Tastenkombi.
Und dann bleibt er bei form_Notify.Close stehen...

Weis jemand warum das passiert???
Delphi-Quellcode:
Procedure NotifyWindow(WindowText: String);
 Var
  form_Notify : TForm;
  Panel : TPanel;
  Memo : TMemo;
  OK : TLabel;
  event_CloseQuery : TCloseQueryEvent;
  event_KeyDown : TKeyEvent;

  Procedure AAFont(ObjFont: TFont);
     Var
      LogFont: TLogFont;
   Begin
    Try
     GetObject(ObjFont.Handle, SizeOf(TLogFont), @LogFont);
     LogFont.lfQuality := ANTIALIASED_QUALITY;
     ObjFont.Handle := CreateFontIndirect(LogFont);
    Except
     Exit;
    End;
   End;

  Function GetKey(Keycode: Integer) : Boolean;
   Begin
    Try
     GetKey := GetAsyncKeyState(KeyCode) <> 0;
    Except
     Exit;
    End;
   End;

  Function OK_Pressed : Boolean;
   Begin
    Try
     If GetKey(VK_LControl) And GetKey(VK_LMenu) And GetKey(Ord('O')) And GetKey(Ord('K'))
     Then OK_Pressed := True
     Else OK_Pressed := False;
    Except
     Exit;
    End;
   End;

  Procedure KeyDown(Self, Sender: TObject; Var Key: Word; Shift: TShiftState);
   Begin
    If OK_Pressed = True Then form_Notify.Close;
   End;

  Procedure CloseQuery(Self, Sender: TObject; Var CanClose: Boolean);
   Begin
    Try
     If OK_Pressed = True
     Then CanClose := True
     Else CanClose := False;
    Except
     Exit;
    End;
   End;

// M A I N ===========================================================================
 Begin
  Try
   Try
    TMethod(event_CloseQuery).Code := @CloseQuery;
    TMethod(event_CloseQuery).Data := Nil;
    TMethod(event_KeyDown).Code := @KeyDown;
    TMethod(event_KeyDown).Data := Nil;
    
    form_Notify := TForm.Create(Nil);
    form_Notify.Caption := 'NotifyWindow';
    form_Notify.Height := 374;
    form_Notify.Width := 583;
    form_Notify.BorderStyle := bsSingle;
    form_Notify.BorderIcons := [];
    form_Notify.Color := 898061;
    form_Notify.FormStyle := fsStayOnTop;
    form_Notify.Left := (Screen.Width - form_Notify.Width) Div 2;
    form_Notify.Top := (Screen.Height - form_Notify.Height) Div 2;
    form_Notify.OnCloseQuery := event_CloseQuery;
    form_Notify.OnKeyDown := event_KeyDown;

    Panel := TPanel.Create(Nil);
    Panel.Borderstyle := bsNone;
    Panel.Color := 898061;
    Panel.Enabled := False;
    Panel.Height := 296;
    Panel.Width := 549;
    Panel.Left := 14;
    Panel.Top := 17;
    Panel.Parent := form_Notify;

    Memo := TMemo.Create(Nil);
    Memo.Alignment := taLeftJustify;
    Memo.BorderStyle := bsSingle;
    Memo.Color := 898061;
    Memo.Font.Color := clBlack;
    Memo.Font.Size := 14;
    Memo.Font.Name := 'VerdanaB';
    Memo.Font.Style := [fsBold];
    Memo.Height := 284;
    Memo.Width := 537;
    Memo.Left := 6;
    Memo.Top := 6;
    Memo.ReadOnly := True;
    Memo.ScrollBars := ssNone;
    Memo.Parent := Panel;
    Memo.Text := WindowText;

    OK := TLabel.Create(Nil);
    OK.Caption := 'CTRL + ALT + O + K';
    OK.Color := 898061;
    OK.Font.Color := clBlue;
    OK.Font.Name := 'VerdanaB';
    OK.Font.Size := 14;
    OK.Font.Style := [fsBold];
    OK.AutoSize := True;
    OK.Left := 375;
    OK.Top := 317;
    OK.Parent := form_Notify;

    AAFont(Memo.Font);
    AAFont(OK.Font);
    form_Notify.ShowModal;
   Finally
    FreeAndNil(OK);
    FreeAndNil(Memo);
    FreeAndNil(Panel);
    FreeAndNil(form_Notify);
   End;
  Except;
   Exit;
  End;
 End;

Procedure TForm1.Button1Click(Sender: TObject);
 Begin
  NotifyWindow('Coole Sache !!!' +#13#10+ 'Haaa, Das is` ja`n Ding!!!');
 End;
So kann man das natürlich auch machen, aber das ist nicht so praktisch und ich brauche 'ne globale Variable, sonst kennt er form_Notify nicht.
Das hab' ich mal gesehen in einem Post von Omata... funktioniert gut.
Delphi-Quellcode:
 Type
  TEvents = Class
   Class Procedure CloseQuery(Sender: TObject; Var CanClose: Boolean);
   Class Procedure KeyDown(Sender: TObject; Var Key: Word; Shift: TShiftstate);
 End;

Class Procedure TEvents.CloseQuery(Sender: TObject; Var CanClose: Boolean);
 Begin
  Try
   If OK_Pressed = True
   Then CanClose := True
   Else CanClose := False;
  Except
   Exit;
  End;
 End;

Class Procedure TEvents.KeyDown(Sender: TObject; Var Key: Word; Shift: TShiftstate);
 Begin
  If OK_Pressed = True Then form_Notify.Close; //globale Variable !!!
 End;
Früher hab' ich immer bei FormKeyDown "If Sender = form_Notify Then...." benutzt, aber da brauche ich auch 'ne globale Variable oder???
Gut, für das Panel braucht man noch "uses ExtCtrls"...

Gruß
Martin
  Mit Zitat antworten Zitat