Formulare
Wie manipuliere ich die Form eines Formulars ( z. B. Formular als Kreis )?
Dafür gibt es die sogenannten "Regions":
procedure TForm1.FormCreate(Sender:TObject); var HR: HRgn; n:array[0..3] of TPoint; begin n[0]:=Point(Width div 2,1); n[1]:=Point(1, Height div 2); n[2]:=Point(Width div 2,Height); n[3]:=Point(Width, Height div 2); HR:= CreateEllipticRgn (0, 0, Width, Height); {oder eine Raute: HR:= CreatePolygonRgn(n, 4, Alternate);} SetWindowRgn(Handle, HR, True); end; |
Dieses Beispiel hat Michael Schüle in dclpd gepostet. Die Anregung dazu hat er wohl dem Buch "Borland Delphi 3 für Profis" von Walter Doberenz und Thomans Kowalski aus dem Hanser Verlag entnommen.
Applications running in different resolutions
1. I belive I have found the answer to a lot of peoples questions (mine included) about Applications that run in different resolutions.
The problem is if you develop an Application in one resolution, say 1024x768 using Large fonts, then try and run it at say 800x600 using Small fonts. Labels get chopped and components are different sizes than when designed. Other weird looking things happen too.
Well, I found that by changing the PITCH property on the FONT to VARIABLE instead of DEFAULT that it looks the same in every resolution.
This should be done to every component and to the Form itself. (Does anyone know where "Default" is set?)
2. After much experimenting, it appears that delphi figures some font size and scaling factors at design time, and doesn't re-calculate them at run time. This seems to cause some of the "special effects" at different resolutions (i.e. edit boxes with only half of the text visible, and labels partly chopped off).
To get around this, make delphi re-calculate these values, by simply assigning the main form's font at run time (in the oncreate event), as well as any other controls in which you didn't use the ParentFont option.
I think calling the Font's OnChange event will correct the problem as well, but I haven't tried it yet.
I sincerely wish we could get a difinitive answer from borland, or someone very knowledgeable on this topic.
On a side note, if I tried to re-assign PixelsPerInch, or the scaled properties at run time, I got a general protection fault (even the example code in the help file gave a GPF).
Code-Schnipsel dafür:
Auf jeden Fall habe ich mal ein Stueck Code dafuer gekriegt, das zu meiner grossen Ueberraschung bis jetzt jedes Formular mitsamt allem Geraffel drauf prima skaliert hat. Es sind nur ein paar Zeilen im FormCreate des Haupt- formulars und dazu zwei Konstanten (global definiert):
const ScreenWidthDev = XXX; ScreenHeightDev = YYY; {statt XXX und YYY die Aufloesung zur Entwicklungszeit eintragen. Angeblich soll der Code am besten von der hoechsten Aufloesung runterskalieren. Ich musste aber immer von 640/480 (die hohen Aufloesungen kommen bei mir nicht so gut) hochskalieren und es ging auch.} procedure TForm1.FormCreate(Sender: TObject); var x,y: Integer; // f. Bildschirmauflösung begin Scaled:= true; x:= Screen.Width; y:= Screen.Height; if (x<>ScreenWidthDev) or (y<>ScreenHeightDev) then begin Form1.Height:= (Form1.ClientHeight*y div ScreenHeightDev) + Form1.Height - Form1.ClientHeight; Form1.Width:= (Form1.ClientWidth*y div ScreenWidthDev) + Form1.Width - Form1.ClientWidth; ScaleBy(x,ScreenWidthDev); end; // of if |
Worueber ich mich immer wieder wundern kann: Mit dieser Methode werden ALLE Fenster des Projekts skaliert, obwohl doch eigentlich ausdruecklich nur Form1 skaliert wird. Komisch.
Ein Fenster einer Anwendung immer zuoberst anzeigen, auch bei minimiertem Hauptfenster
Manchmal möchte man, daß geöffnete (Unter-)Fenster einer Anwendung auf dem Desktop bleiben, wenn das Hauptfenster minimiert wird, oder daß ein Fenster immer im Vordergrund bleibt, auch wenn es nicht den Fokus hat.
Ich will mal kurz zeigen, wie man das zur Laufzeit einstellen kann:
//OnTop.. SetWindowPos(Handle, HWND_TOPMOST, Left,Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); //..und zurück: SetWindowPos(Handle, HWND_NOTOPMOST, Left, Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); //OnDesktop.. SetWindowLong(Handle, GWL_HWNDPARENT, 0); //..und zurück: SetWindowLong(Handle, GWL_HWNDPARENT, Application.Handle); |
Wie kann ich ein Fenster transparent darstellen?
Zwei einfache Tricks, um ein Fenster "unsichtbar", also transparent zu zeichnen:
1. So kann man die Transparenz zur Laufzeit umschalten:
Procedure MakeWindowTransparent (Form: TForm); Var CurrentStyle : LongInt; Begin Form.Visible := False; CurrentStyle := GetWindowLong(Form.Handle, GWL_EXSTYLE); SetWindowLong(Form.Handle, GWL_EXSTYLE, CurrentStyle Or WS_EX_TRANSPARENT); Form.Visible := True; End; {Paul Röttgen} Procedure MakeWindowOpaque (Form: TForm); Var CurrentStyle : LongInt; Begin Form.Visible := False; CurrentStyle := GetWindowLong (Form.Handle, GWL_EXSTYLE); SetWindowLong(Form.Handle, GWL_EXSTYLE, CurrentStyle And Not WS_EX_TRANSPARENT); Form.Visible := True; End; {Paul Röttgen} |
2. So wird ein Fenster transparent erstellt:
procedure TForm1.FormCreate(Sender: TObject); begin Form1.Brush.Style := bsClear; Form1.BorderStyle := bsNone; end; |
Wie erzeuge ich ein Formular ohne Titelleiste?
1. Möglichkeit:
TForm.BorderStyle auf bsNone zu setzen. Leider ergibt das ein Formular, das dann gar keine Begrenzung mehr hat. Abhilfe schafft ein TBevel, dessen Align man auf alClient setzt.
2. Möglichkeit:
Die Methode CreateParams überschreiben, in der der Parameter-Record für die Fenstererzeugung initialisiert wird:
{ Private Deklaration } procedure CreateParams(var Params : TCreateParams); override; ... { Implementation: } procedure TForm1.CreateParams(var Params : TCreateParams); begin Inherited Createparams(Params); with Params do Style := (Style or WS_POPUP) and not WS_DLGFRAME; end; |
3. Möglichkeit:
In der OnCreate-Methode des Formulars die API-Funktion "SetWindowLong" aufrufen:
procedure TForm1.FormCreate(Sender: TObject); begin SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) and not WS_CAPTION); ClientHeight:=Height; end; |