Delphi Can
Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - Baskı Önizleme

+- Delphi Can (http://www.delphican.com)
+-- Forum: Delphi (http://www.delphican.com/forumdisplay.php?fid=3)
+--- Forum: Access violation (http://www.delphican.com/forumdisplay.php?fid=136)
+--- Konu Başlığı: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) (/showthread.php?tid=1309)

Sayfalar: 1 2 3


Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - Tuğrul HELVACI - 06-09-2017

Forumda gördüğüm Windows mesajlaşma ile ilgili bir konuya müteakiben; +10 puan kıymetinde bir soru yönlendirmek istedim sizlere. Bu eğlencelik aktivitede sizlerden beklenenler aşağıdaki gibidir:
  • 2 adet VCL uygulamanız olacak.
  • Her iki uygulamada da formunuz üzerinde bir adet button olacak.
  • Birinci uygulamanın button'una basıldığında 30 saniye uyuma kodu yazacaksınız. Aynı zamanda bu uygulama üzerinde diğer uygulamadan gönderilecek olan mesajı yakalayacaksınız ve ShowMessage ile ekrana bir bildirim mesajı çıkartacaksınız.
  • Ardından ikinci uygulamanın buttonuna basacaksınız ve birinci uygulamanın ana penceresinin handle'ını bulacak, ardından ilgili pencereye sizin belirlediğiniz bir mesajı göndereceksiniz.(Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. ile ve Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. ile)
  • Ne olduğunu ve nedenlerini izah edeceksiniz.
  • İkinci uygulamanız kilitlendi ise, bunu nasıl aşabileceğinizi belirteceksiniz.
Başarılar ve iyi eğlenceler Smile

Doğru cevabı ilk veren arkadaşımız +10 puanı alacak. Diğer arkadaşlarımıza da teselli puanları vereceğim Shy

Not: Mesajınızı bir kerede doğru göndermeye gayret edin. Editlediğiniz mesaj doğru da olsa +10 puan veremeyeceğim.


Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - The_aLiEn - 06-09-2017

(06-09-2017, Saat: 16:29)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
  • Her iki uygulamada da formunuz üzerinde bir adet button olacak.

Button ne kadar büyükse proje de o kadar büyük olacak mı peki? Big Grin


Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - Tuğrul HELVACI - 06-09-2017

(06-09-2017, Saat: 16:46)The_aLiEn Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
(06-09-2017, Saat: 16:29)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
  • Her iki uygulamada da formunuz üzerinde bir adet button olacak.

Button ne kadar büyükse proje de o kadar büyük olacak mı peki? Big Grin

Big Grin Tabii


Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - The_aLiEn - 06-09-2017

Tutamadım kendimi, servise binmedim Big Grin

1. uygulama:

const
  WM_P2       = WM_User + 11863;

  cSecond     = 30;
  cSleepTime  = cSecond * 1000;

type
  Tp1Frm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private    procedure WM_P2_Message(var msg: TMessage); message WM_P2;
  public
  end;

procedure Tp1Frm1.WM_P2_Message(var msg: TMessage);
begin
  ShowMessage('WM_P2_Message mesajı işleniyor');

  // some code..

  ShowMessage('WM_P2_Message mesajı işlendi');
end;

procedure Tp1Frm1.Button1Click(Sender: TObject);
begin
  Sleep(cSleepTime);
end;


Bu da 2. uygulama:

const
  WM_P2       = WM_User + 11863;

procedure TForm2.Button1Click(Sender: TObject);
var
  p1Handle: HWND;
begin
  p1Handle := FindWindow('Tp1Frm1', nil);

  if p1Handle <> 0 then
    if IsWindow(p1Handle) then
      PostMessage(p1Handle, WM_P2, 0, 0);
      //SendMessage(p1Handle, WM_P2, 0, 0);

  ShowMessage('DONE');
end;


Şimdi gelelim açıklamalara:

Senkron ve asenkron kavramlarını hemen hepimiz biliyoruz değil mi? ( Aslında bu cümleden sonra devam etmeme gerek olmamalı Smile) )

API'leri bilmiyorsak hemen dökümana başvuruyoruz; kaçamazsınız...

Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.

PostMessage der ki, HWND parametresi ile verdiğin pencerenin mesaj kuyruğuna, verdiğin mesajı, verdiğin parametrelerle BIRAKIRIM, MESAJIN İŞLENİP İŞLENMEDİĞİYLE İLGİLENMEM, GERİ DÖNERİM.

SendMessage da der ki, HWND parametresi ile verdiğin pencerenin mesaj kuyruğuna, verdiğin mesajı, verdiğin parametrelerle GÖNDERİRİM VE MESAJIN İŞLENMESİNİ BEKLERİM.

Neler olduğu ve neden olduğu tamemen bu bekleme/beklememe mekanizmasının çeşitli kombinasyonları. Şöyle örneklendireyim:

Sleep(30*1000) gibi bir uyuma verdiğinizde ilgili thread bloklanacak olduğu için, varsa, o thread'in mesaj kuyruğu da işlenemeyecektir.

Bu mesaj kuyruğuna SendMessage ile gönderilen tüm mesajlar, thread bloklandığı için işlenemeyecek; gönderici tarafı da alıcıdan bir işlendi cevabı beklediği ve alamadığı için SendMessage içinde bloklanacaklardır.

Bu mesaj kuyruğuna PostMessage ile gönderilen tüm mesajlar, thread bloklandığı için işlenemeyecek FAKAT, gönderici tarafı herhangi bir işlendi cevabı beklemediği için bloklanmayacak ve çalışmasına devam edecektir.

Her iki durum için de, Sleep süresi bitip ilgili thread tekrar tarifelendiğinde alıcı taraftaki kuyruk tüketilmeye devam edilecek ve kuyruktaki mesajlar işlenecektir.

Nasıl aşılabileceğine dair bilgiyi çoktan verdim aslında Smile)

(06-09-2017, Saat: 17:25)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
(06-09-2017, Saat: 16:46)The_aLiEn Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Button ne kadar büyükse proje de o kadar büyük olacak mı peki? Big Grin

Big Grin Tabii

Abi buyur o zaman Smile)

[attachment=154]

--

[attachment=155]


Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - cemaliozan - 06-09-2017

(06-09-2017, Saat: 16:29)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Forumda gördüğüm Windows mesajlaşma ile ilgili bir konuya müteakiben; +10 puan kıymetinde bir soru yönlendirmek istedim sizlere. Bu eğlencelik aktivitede sizlerden beklenenler aşağıdaki gibidir:
  • 2 adet VCL uygulamanız olacak.
  • Her iki uygulamada da formunuz üzerinde bir adet button olacak.
  • Birinci uygulamanın button'una basıldığında 30 saniye uyuma kodu yazacaksınız. Aynı zamanda bu uygulama üzerinde diğer uygulamadan gönderilecek olan mesajı yakalayacaksınız ve ShowMessage ile ekrana bir bildirim mesajı çıkartacaksınız.
  • Ardından ikinci uygulamanın buttonuna basacaksınız ve birinci uygulamanın ana penceresinin handle'ını bulacak, ardından ilgili pencereye sizin belirlediğiniz bir mesajı göndereceksiniz.(Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. ile ve Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. ile)
  • Ne olduğunu ve nedenlerini izah edeceksiniz.
  • İkinci uygulamanız kilitlendi ise, bunu nasıl aşabileceğinizi belirteceksiniz.
Başarılar ve iyi eğlenceler Smile

Doğru cevabı ilk veren arkadaşımız +10 puanı alacak. Diğer arkadaşlarımıza da teselli puanları vereceğim Shy

Not: Mesajınızı bir kerede doğru göndermeye gayret edin. Editlediğiniz mesaj doğru da olsa +10 puan veremeyeceğim.

 Doğru anladım mı bilmiyorum ama şöyle bir şey mi olacaktı ?
unit Unit1;  // Uyuyan 

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

Const WM_USERMSG_UYAN = WM_USER + 999;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure WMUSERMSGUYAN(Var Msg : TMessage);message WM_USERMSG_UYAN;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Sleep(30000);
end;

procedure TForm1.WMUSERMSGUYAN(var Msg: TMessage);
begin
  Application.MessageBox('Uyan Uyan Uyan','Uyandırma Servisi',mb_iconinformation);
end;

end.


unit Unit2; // Uyandıran

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

Const WM_USERMSG_UYAN = WM_USER + 999;

type
  TmyThread = Class(TThread)
  private
    FHnd : Hwnd;
  Protected
    procedure Execute; override;
  Public
    constructor Create(Const AHnd: THandle);
    destructor Destroy; override;
  End;


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
 Var
   Hnd : Hwnd;
   T   : TmyThread;
begin
  Hnd := FindWindow('TFORM1', 'UYUYAN GUZEL');
  if Hnd <> 0 then
   T  := TmyThread.Create(Hnd);

end;


{ TmyThread }

constructor TmyThread.Create(const AHnd: THandle);
begin
  Inherited Create(True);
  FreeOnTerminate   := True;
  FHnd              := AHnd;
  Resume;
end;

destructor TmyThread.Destroy;
begin

  inherited;
end;

procedure TmyThread.Execute;
begin
  inherited;
  SendMessage(FHnd, WM_USERMSG_UYAN, 0, 0);
end;

end.

1. Uyuyan uygulama kanal olmadan uyandırılmak istenince Tuğrul hocamın dediği gibi uyandıran kilitlendi. Sebebi sleep çağırısıyla windows uyuyan uygulamayı askıya alıp denetimi eşit veya daha yüksek önceliğe sahip diğer işlemlere geçirmesi. Uyandıran tarafından uyuyana geçilen Sendmessage  windows un askıya aldığı uygulamaya ulaşmadığından uyandıran tarafından sendmessage dönüş değeri uyandırana dönmüyor.

2.  Uyandıranın gönderimini Kanalla windows mesaj kuyruğuna ekleyince ve 30 saniyelik uyuma sona erince uyuyan uygulama mesajı aldı ve kilitlenme sorunu çözüldü.
96zSCR


Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - savasabd - 06-09-2017

Arkadaşlar ben Bilgisyarımdan uzakta olduğum için cevap veremiyorum,ama nacizane fikrimi söyleyeyim,bence hocamın istediği fonksiyon SendMessageTimeout fonksiyonu.


Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - cemaliozan - 06-09-2017

(06-09-2017, Saat: 18:45)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Arkadaşlar ben Bilgisyarımdan uzakta olduğum için cevap veremiyorum,ama nacizane fikrimi söyleyeyim,bence hocamın istediği fonksiyon SendMessageTimeout fonksiyonu.

Bencede hoca farklı bir yöntem istiyor velakin sendmessage api fonksiyonunu görünce aklıma başka bir sey gelmedi. Postmessage ile denemedim fakat ali en de iyi anlatmış.


Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - ismailkocacan - 06-09-2017

1. uygulamada Sleep ile thread bloklanıp, 2. uygulamadan da windows mesajı gönderilip aynı zamanda 2. uygulamanın donmaması/kilitlenmemesi isteniyorsa Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. ve Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. dışında Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. callback fonksiyonu kullanılabilir.

SendMessageCallback fonksiyonu ile ilgili pencereye Windows mesajı gönderilir ve Windows procedure'ün çalışması beklenmeden hemen geriye dönülür.Windows procedure ilgili mesajı işledikten sonra yani çalıştıktan sonra, belirtilen callback fonksiyonu çağırarak mesajı işlediğini bildirir.

Dolayısı ile 1. uygulama Sleep ile bloklansa bile, 2. uygulamadan SendMessageCallback ile mesaj gönderildiğinde bir kilitlenme meydana gelmez.

Callback fonksiyon prototipi.
  VOID CALLBACK SendAsyncProc(
   _In_ HWND      hwnd,
   _In_ UINT      uMsg,
   _In_ ULONG_PTR dwData,
   _In_ LRESULT   lResult
 );

procedure SendAsyncProc(HWND: HWND; Msg: UINT; wParam: wParam;
 dwData: ULONG_PTR; lResult: LRESULT);
begin
 ShowMessage('mesaj işlendi');
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  p1Handle: HWND;
  dwData: UIntPtr;
begin
  p1Handle := FindWindow(nil, 'MainApp');
  if p1Handle = 0 then exit;
  if not IsWindow(p1Handle) then exit;

  dwData := 31;
  SendMessageCallback(p1Handle, WM_P2, 0, 0, @SendAsyncProc, dwData);

 ShowMessage('DONE');
end;




Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - SecondLife - 06-09-2017

Birinci Form

unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

 //Declare the message body name
const
Mymsg= 'delphican';

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
WProc: Pointer;
DelphicanMmsg: cardinal;
implementation

{$R *.dfm}
function NewWndProc(Handle: hWnd; Msg, wParam, lParam: Cardinal): LongInt; stdcall;
begin
if Msg= DelphicanMmsg then
begin
MessageBox(handle, 'Uygulama Mesajı', '', MB_OK);
Result:= 1;
end else
Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
Sleep(30000);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
DelphicanMmsg:= RegisterWindowMessage(Mymsg);

end;

initialization
WProc := Pointer(SetWindowLong(Application.Handle, gwl_WndProc,
Integer(@NewWndProc)));
end.


İkinci Form

unit Unit2;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
const
Mymsg= 'delphican';
type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
DelphicanMmsg: cardinal; //This is the actual handle of the message
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(HWND_BROADCAST, DelphicanMmsg, 0, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
DelphicanMmsg:= RegisterWindowMessage(Mymsg);

end;

end.



Cvp: Windows Mesajlaşma Sistemi Hk. Soru (+10 Puan) - Tuğrul HELVACI - 07-09-2017

Arkadaşlar, öncelikle ilginize teşekkür ederim. Bu kısım altında yorumda bulunan ve çözüm sunan tüm arkadaşlarımıza bir kısım puanlar verdim.

Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. arkadaşımıza uzun ve detaylı açıklamasından ötürü teşekkür ederim. Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. API'sinden bahsetmediği için 2 puanını kırdım Smile

Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. arkadaşımıza doğru çözümü sunduğu için teşekkür ederim. Tam puan. Wink