Form Uygulaması için Ekran Maskeleme

Yapmak istediğiniz işle ilgili doğru bileşeni bulmak için burayı kullanabilirsiniz. Sadece bulmak için, diğer sorular Programlama forumuna lütfen.
Forum kuralları
Bu forum sadece yapacağınız işle alakalı doğru bileşeni bulmak içindir. Şöyle bir şey yapmam lazım, hangi bileşeni kullanıyım diyorsanız, doğru yerdesiniz.
Cevapla
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 23 Şub 2016 04:09

Merhaba değerli üyeler,
Delphi masaüstü uygulamamda uzun süren işlemlerde kullanıcının form üzerinde gezinmesini sağa sola tıklamasını engellemek amacıyla formu yada uygulamamın tamamını hiç olmadı komple ekranı maskeleyerek işlem süresince bekletmek istiyorum, web sayfalarında sık sık kullanılan bu yöntemi VCL de uygulamam için yöntem yada hazır bileşen önerilerinizi bekliyorum.
iyi çalışmalar.
Volkan KAMADAN
www.polisoft.com.tr

Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1310
Kayıt: 07 May 2009 09:42
Konum: İstanbul
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen SimaWB » 24 Şub 2016 09:24

Benim ilk aklıma gelen çözüm: tüm ekranı kaplayan ikinci bir form. Gerektiğinde bu form gösterilir. Gösterilirken ana formun Enabled özelliği False yapılır, işlem bitince ikinci form kapatılır ve ana formun Enabled özelliği True yapılır. (İkinci formun BorderStyle ve AlphaBlend değerleri değiştirilerek görsellik kazandırılabilir)
There's no place like 127.0.0.1

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 24 Şub 2016 09:29

Merhaba @SimaWB önerin için teşekkürler, şuan benzeri şekilde testler yapıyorum , nadiren aktif formun kontrol dışı arkaya kaçması vb gibi durumlar oluşuyor , içime sinen sonucu paylaşacağım.
iyi çalışmalar.
Volkan KAMADAN
www.polisoft.com.tr

Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1310
Kayıt: 07 May 2009 09:42
Konum: İstanbul
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen SimaWB » 24 Şub 2016 09:42

Onun için 2. formun PopupParent özelliğini ana form olarak atamanız öneriliyor. PopupParent ve PopupMode özelliklerini araştırabilirsiniz.
There's no place like 127.0.0.1

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 24 Şub 2016 09:46

Bu çok iyi bir bilgi @SimaWB tekrar teşekkür ederim.
Volkan KAMADAN
www.polisoft.com.tr

anonymousdelphicoder
Üye
Mesajlar: 152
Kayıt: 16 May 2014 10:23

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen anonymousdelphicoder » 14 Mar 2016 11:21

Neden bu kadar ilkel yontemlerle tasarim ve kod yazilir anlamiyorum. Yapacaginiz sey cok basit pencerenin ClientHandle hwnd i alip getdc ile context i aldikdan sonra bir bitmapin canvasina bitblt ile cizdirirsiniz. Daha sonra GDI+ kullanarak veya baska bir grafik kutuphanesi ile bu resmin Matrixleriyle oynayip resmi hafif karartabilirsiniz daha sonra bunu TImage ye yukleyip gosterirsiniz olay bu.

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 14 Mar 2016 12:16

anonymousdelphicoder yazdı:Neden bu kadar ilkel yontemlerle tasarim ve kod yazilir anlamiyorum. Yapacaginiz sey cok basit pencerenin ClientHandle hwnd i alip getdc ile context i aldikdan sonra bir bitmapin canvasina bitblt ile cizdirirsiniz. Daha sonra GDI+ kullanarak veya baska bir grafik kutuphanesi ile bu resmin Matrixleriyle oynayip resmi hafif karartabilirsiniz daha sonra bunu TImage ye yukleyip gosterirsiniz olay bu.
Merhaba ,
Öncelikle öneri için teşekkürler.
Bildiğiniz gibi programlama aleminde çoğu zaman çözüme ulaşmanın bir çok yolu vardır, şuan ki durumda böyle RAD mantığının arkasına sığınarak ve VCL in hazır nimetlerinden yararlanarak kendimize göre içimize sinen ve en hızlı uygulayabileceğimiz yöntemi seçtik.

Açıkçası diğer arkadaşların önerdiği ve tercih ettiğimiz yönteme bir çok şeyi hazır olduğu için "HAZIR" denilebilir ama sizin deyiminizle "İLKEL" bir yöntem olduğunu düşünmüyorum.

yazılımcılar yeni şeyler öğrenmeli hazır olan şeylerin derinleriklerine inip bu nasıl oluyor arkadaş diyerek temrin projeleri yapmalı fakat gerçek dünyada en hızlı şekilde sonuca varmak için de, zaten keşfedilmiş yapılmış ve sunulmuş yapıları kullanmakta hiç bir sakınca görmüyorum RAD kavramı ve VCL in doğası ve amacı da zaten bu değil mi?

Kolay gelsin.
Volkan KAMADAN
www.polisoft.com.tr

Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3040
Kayıt: 17 Nis 2006 07:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen sabanakman » 14 Mar 2016 02:05

Benzeri bir işlem için bende denk bir mantık kullanmaktayım. Mesela kullanıcıdan şifre soracağım zaman formun erişilmez olması için aynı boyutta ve konumda bir saydam formu, ilgili formun üzerinde göstermekteyim. Belirttiğim bir paneli de bu saydam form üzerinde modal açılan başka formda göstererek kullanıcıdam isim ve şifre girmesini sağlamakta ve asıl forma müdahale etmesine engel olmaktayım. Belki, bu yapı size ip ucu verebilir.
UntSaydamForm.dfm dosyası

Kod: Tümünü seç

object SaydamForm: TSaydamForm
  Left = 233
  Top = 92
  BorderStyle = bsNone
  Caption = 'SaydamForm'
  ClientHeight = 149
  ClientWidth = 204
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCloseQuery = FormCloseQuery
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  OnKeyDown = FormKeyDown
  DesignSize = (
    204
    149)
  PixelsPerInch = 96
  TextHeight = 13
  object Kapat: TBitBtn
    Left = 124
    Top = 113
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Caption = 'Kapat'
    TabOrder = 0
    OnClick = KapatClick
  end
end
UntSaydamForm.pas dosyası

Kod: Tümünü seç

unit UntSaydamForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;

type
  TSaydamForm = class(TForm)
    Kapat: TBitBtn;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure KapatClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    _AktifKontrol:TWinControl;
    _CanClose:Boolean;
    AsilForm,EkForm:TForm;
    Kontrolcu:TTimer;
    Kontrol:TWinControl;
    procedure SetLayeredAttribs;
    procedure KontrolcuTimer(Sender: TObject);
    procedure EkFormFormActivate(Sender: TObject);
  public
    { Public declarations }
    function Exec(const Panel:TWinControl):Boolean;
    procedure FormuKapat;
  end;

var
  SaydamForm: TSaydamForm = nil;

procedure Bekle(C:Cardinal=500);
procedure YanSon(const Ctrl:TControl);//const KacKere:Integer=3;const GosterenSure:Cardinal=250;const GizlenenSure:Cardinal=150

function PanelModal(const Panel:TWinControl;const CanClose:Boolean=True;const AktifKontrol:TWinControl=nil):Boolean;

implementation

{$R *.dfm}

procedure Bekle(C:Cardinal);
begin
  C:=C+GetTickCount;
  while GetTickCount<C do
   Application.ProcessMessages;
end;

procedure YanSon(const Ctrl:TControl);
begin
  if Ctrl.Visible then begin
    Ctrl.Hide;
    Bekle(90);
  end;
  Ctrl.Show;
  Bekle(350);
  Ctrl.Hide;
  Bekle(50);
  Ctrl.Show;
  Bekle(370);
  Ctrl.Hide;
  Bekle(65);
  Ctrl.Show;
end;

function PanelModal(const Panel:TWinControl;const CanClose:Boolean;const AktifKontrol:TWinControl):Boolean;
begin
  if not Assigned(SaydamForm) then SaydamForm:=TSaydamForm.Create(Application);
  SaydamForm._CanClose:=CanClose;
  SaydamForm._AktifKontrol:=AktifKontrol;
  Result:=SaydamForm.Exec(Panel);
end;

procedure TSaydamForm.SetLayeredAttribs;
const
  FAlphaBlend=True;
  FTransparentColor=False;
  FTransparentColorValue:TColor=clBlack;
  FAlphaBlendValue=125;

  cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
  cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
var
  AStyle: Integer;
begin
  if not (csDesigning in ComponentState) and
    (Assigned(SetLayeredWindowAttributes)) and HandleAllocated then
  begin
    AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
    if FAlphaBlend or FTransparentColor then
    begin
      if (AStyle and WS_EX_LAYERED) = 0 then
        SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
      SetLayeredWindowAttributes(Handle, FTransparentColorValue, FAlphaBlendValue,
        cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
    end
    else
    begin
      SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
      RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
    end;
  end;
end;

procedure TSaydamForm.EkFormFormActivate(Sender: TObject);
var Edt:TEdit;
begin
  Edt:=nil;
  if AsilForm.ActiveControl is TEdit then Edt:=TEdit(AsilForm.ActiveControl)
  else if EkForm.ActiveControl is TEdit then Edt:=TEdit(EkForm.ActiveControl);
  if Assigned(Edt) then begin
    Edt.SelLength:=0;
    Edt.SelStart:=Length(Edt.Text);
  end;
  if Assigned(_AktifKontrol) then try
    _AktifKontrol.SetFocus;
  except
  end;
  _AktifKontrol:=nil;{}
end;

procedure TSaydamForm.FormCreate(Sender: TObject);
begin
  SetLayeredAttribs;
  EkForm:=TForm.Create(Application);
  EkForm.KeyPreview:=True;
  //EkForm.OnKeyDown:=Self.OnKeyDown;
  //EkForm.OnKeyDown:=Self.OnKeyDown;
  EkForm.OnKeyDown:=Self.OnKeyDown;
  EkForm.BorderStyle:=bsNone;
  EkForm.Position:=poDesigned;
  EkForm.OnActivate:=EkFormFormActivate;
  EkForm.OnCloseQuery:=FormCloseQuery;
  Kontrolcu:=TTimer.Create(EkForm);
  Kontrolcu.OnTimer:=KontrolcuTimer;
  Kontrolcu.Interval:=125;
  //EkForm.Hide;
end;

function TSaydamForm.Exec(const Panel: TWinControl): Boolean;
 function ilkCtrl(const Pnl:TWinControl):TWinControl;
 var i:Integer; Ctrl:TWinControl;
 begin
   Result:=nil;
   for i := 0 to Pnl.ControlCount-1 do if Pnl.Controls[i] is TWinControl then begin
     Ctrl:=TWinControl(Pnl.Controls[i]);
     if not Assigned(Result) or (Ctrl.TabOrder<Result.TabOrder) then
      Result:=Ctrl;
   end;
   if Assigned(Result) and (Result.ControlCount>0) then
    Result:=ilkCtrl(Result);
 end;
var Form:TForm; L,T:Integer; OrjParent:TWinControl; V:Boolean;
begin
  Form:=Application.MainForm;
  Kontrol:=Panel;
  if Assigned(Panel) then begin
    L:=Panel.Left;
    T:=Panel.Top;
    OrjParent:=Panel.Parent;
    V:=Panel.Visible;
    Form:=TForm(GetParentForm(Panel));
  end else begin
    L:=0;
    T:=0;
    OrjParent:=nil;
    V:=True;
  end;
  Kapat.Visible:=not Assigned(Panel);
  if Assigned(Form) then begin
    //Self.Parent:=Form;
    //Self.Align:=alClient;
    Self.Left:=Form.Left;
    Self.Top:=Form.Top;
    Self.Width:=Form.Width;
    Self.Height:=Form.Height;
  end;
  //Self.PopupParent:=Form;
  Self.Show;
  AsilForm:=Form;
  if Assigned(Panel) then begin
    EkForm.Width:=Panel.Width;
    EkForm.Height:=Panel.Height;
    EkForm.Left:=Self.Left+((Self.Width-Panel.Width) div 2);
    EkForm.Top:=Self.Top+((Self.Height-Panel.Height) div 2);
    EkForm.PopupParent:=Self;
    Panel.Parent:=EkForm;
    Panel.Left:=0;
    Panel.Top:=0;
    Panel.Show;
    if not Assigned(_AktifKontrol) then _AktifKontrol:=ilkCtrl(Panel);
    Application.ProcessMessages;
    EkForm.ShowModal;
    Self.Close;
    Panel.Visible:=V;
    Panel.Parent:=OrjParent;
    Panel.Left:=L;
    Panel.Top:=T;
  end;
  Result:=True;
end;

procedure TSaydamForm.KapatClick(Sender: TObject);
begin
  Close;
end;

procedure TSaydamForm.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_ESCAPE:if (Sender is TForm) and _CanClose then TForm(Sender).Close;
  end;
end;

procedure TSaydamForm.KontrolcuTimer(Sender: TObject);
begin
  if EkForm.Visible and Assigned(Kontrol) and not Kontrol.Visible then EkForm.Close;
end;

procedure TSaydamForm.FormDestroy(Sender: TObject);
begin
  if Sender=SaydamForm then SaydamForm:=nil;
end;

procedure TSaydamForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:=Self._CanClose;
end;

procedure TSaydamForm.FormuKapat;
begin
  _CanClose:=True;
  Kontrol.Hide;
  Close;
  EkForm.Close;
end;

end.
Bu yapıyı da aşağıdaki şekilde kullanmaktayım.

Kod: Tümünü seç

PanelModal(pnlSifre, False, edtKullanici);
ve

Kod: Tümünü seç

procedure TfrmZrfSfreciAna.btnSifreTamamClick(Sender: TObject);
begin
  if SifreTamam then SaydamForm.FormuKapat;
end;
En son sabanakman tarafından 14 Mar 2016 05:22 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 14 Mar 2016 05:03

Merhaba @sabanakman,
Değerli paylaşımın için çok teşekkür ederim,
Aslında bu konuyu açarken (kullandıysanız belki bilirsiniz) UniGUI nin içinde gelen TUniScreenMask bileşeninden yola çıkmıştım , ilgili bileşenin SourceControl ve TargetControl property lerine örneğin SoruceControl e maskelemeyi tetikleyecek kontrolü bağlıyorsunuz, TargetControl e de maskelenecek kontrolü bağlıyorsunuz o gerekeni yapıyordu, sizin örnek te maskelenecek kontrolün dinamik olması çok güzel bir detay oldu. tekrar teşekkürler.
Volkan KAMADAN
www.polisoft.com.tr

gaus
Üye
Mesajlar: 227
Kayıt: 14 May 2014 06:36
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen gaus » 15 Mar 2016 09:27

Merhabalar bu yolu hiç ek bir form yaratmadan yapmak mümkün.@mrmarman hocamızın dediği gibi biraz sihir sanırsam.
Ek form bazı durumlarda sıkıntılı olabiliyor.Ya da threadler falan yaratmak gerekiyor.Ben şöyle bir çözüm buldum

Kod: Tümünü seç

unit bekle;

interface
  uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms;
type
TStatusWindowHandle = type HWND;
function CreateStatusWindow(const Text: string): TStatusWindowHandle;
procedure RemoveStatusWindow(StatusWindow: TStatusWindowHandle);
implementation

function CreateStatusWindow(const Text: string): TStatusWindowHandle;
var
  FormWidth,
  FormHeight: integer;
begin
  FormWidth  := 600;//Genişliğini istediğiniz gibi ayarlayın
  FormHeight := 180;// Yüksekliğini istediğiniz gibi ayarlayın
  result := CreateWindow('STATIC',
                         PChar(Text),
                         WS_OVERLAPPED or WS_POPUPWINDOW or WS_THICKFRAME or SS_CENTER or SS_CENTERIMAGE,
                         (Screen.Width - FormWidth) div 2,
                         (Screen.Height - FormHeight) div 2,
                         FormWidth,
                         FormHeight,
                         Application.Mainform.Handle,
                         0,
                         HInstance,
                         nil);
  ShowWindow(result, SW_SHOWNORMAL);
  UpdateWindow(result);
end;

procedure RemoveStatusWindow(StatusWindow: TStatusWindowHandle);
begin
  DestroyWindow(StatusWindow);
end;

end.
Bu unit ile Static window yaratıyorum.Buraya bir çok daha fonksiyon eklenebilir.Mesela StatusWindow içerisinde ki yazıyı değiştirecek bir procedurde eklenebilir.
Kullanımı ise şöyledir

Kod: Tümünü seç

var 
 hwnd : TStatusWindowHandle;
  begin
   hwnd := CreateStatusWindow('Lütfen Bekleyiniz');
   try
     //işlemler vb. işler
   finally
    RemoveStatusWindow(hwnd);
   end;
  end;
Bu statuswindowlar sayesinde çok daha hızlı formu applicationı dondurmadan işlemler yapabilirsiniz.İşlemler bitincede otomatik olarak kaybolur

Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen vkamadan » 16 Mar 2016 09:37

Merhaba @gaus ,
Örneğinizi test ettim gayet güzel ve kararlı çalışıyor teşekkür ederim.
Aslında TForm dan yardım almaktaki amacım görselliği daha ön planda olan bekleme ekranları ihtiyacımız.
Tekrar teşekkürler.
Volkan KAMADAN
www.polisoft.com.tr

gaus
Üye
Mesajlar: 227
Kayıt: 14 May 2014 06:36
İletişim:

Re: Form Uygulaması için Ekran Maskeleme

Mesaj gönderen gaus » 16 Mar 2016 11:59

http://stackoverflow.com/questions/3211 ... -wait-form
Şu sayfadaki örneği inceleyebilirsiniz. Ama dediğim gibi thread işlemleri uygulamak zorunda kalırsınız.Tprocda sıkıntılı bir işlem.
Xml parsing çalışmaz mesela hata verir.Bittiğini anlamaz.
Sanırım bununla ilgili componenet yazmak şart oldu artık

Cevapla