IPC'nin içinden çıkamadım.

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

Merhaba ustalarım....
IPC'nin içinden çıkamadım derken açıkçası hiç birşey anlayamadım bir test bile yapamadım...
Yapmak istediğim şey 2 program arasında veri göndermek. Veri göndermek dediğimde basit bir dosya ismi veya birkaç satırlık bir liste. Aslında bir string göndermeyi başarabilirsem gerisini her türlü halledebilirdim...

Netten de çok araştırdım Fakat bir türlü çalışan bir örnek yapamadım.

Sizden ricam iki exe arasında string gönderen çalışan ufak bir örnek yapabilirmisiniz acaba.???

Şimdiden çooook çok teşekkür ederim....
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen mrmarman »

Her ikisi de kendi projen mi?
Resim
Resim ....Resim
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

mrmarman yazdı:Her ikisi de kendi projen mi?
evet abi. Sizin eski bir yazınızdan bir harf göndermeyi başardım ama bir metin göndermeliyim. Aslında geldiğim yere kadar metli döngüyle gönderebilirim ama bunu çok da pratik bulmadım. Döngüsüz de halledilir heralde?
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

Sendmessage postmessage v.s detaylı türkçe bir kaynak yokmu? Şöyle derli toplu a dan z ye anlatan bir makale falan. Mesela handle nin bile tam olarak ne olduğunu bilmiyorum. Sadece karşılaştığım durum ve kodlardan dolayı bunun her kontrolün iletişim kurmak için kullanılan bellekteki adresi olduğunu tahmin ediyorum.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen mrmarman »

Şimdiye kadar bir örnek çıkartırsın demiştim.

Mantık basit.
Gönderici
(1) Projen içinde bu işlem için özel bir mesaj kanalı belirleyeceksin. örneğimizde WM_USER + 1234 gibi bir şey olsun. Her iki projen de bu kanal nosunu bilmeli. Yani projene bir mesaj geldiğinde, bu kanala göre nasıl davranacağını bileceksin. Projelerin arası bilgi transferi olup olmadığına bu mesaj kanalına bakarak anlayacak diğer mesajlara kulağını tıkamış olacaksın. :D

(2) Sonra ikinci projenin bilgisayarda çalışıp çalışmadığını kontrol edecek, ürün olarak ana penceresinin HANDLE değerini alacaksın. Bu sana PostMessage işleminde yardımcı olacak.

(3) PostMessage ile projene daha sonra vermek üzere, depo ettiğin yerin adresini alabileceğin bir yere String ifadeyi depo edeceksin.

(4) PostMessage ile ikinci projenin HANDLE'ine mesaj yollayacaksın. Mesajında depo ettiğin adresi de bindireceksin ki ikinci proje depoyu kontrol etsin ve içeriği alabilsin.

Birinci kısım böyle.

Alıcı
(1) Mesaj geldiğinde mesajın ilgilendiğin kanaldan olup olmadığını kontrol edecek. Örneğimizde WM_USER + 1234 kanalı dışındakilere karşı kulağını tıkayacak.

(2) Kanal doğru ise depo edilen yerin adresimi mesaj parametresinden okuyacak.

(3) Depo edilen adrese ulaşıp depo edilen string ifade alınacak.

(4) Depo ile işi bittiğinden depo boşaltılacak.

String depo edebileceğin yerler nereler.
(a) GlobalAddAtom ile belli bir hafıza bloğu
(b) Registry'de belli bir aktif USER kısmı
(c) HardDiskin aktif user için erişim kısıtı olmayan belirli bir konumuna dosya olarak.
(d) ... aklına gelebilecek bir lokasyon
Resim
Resim ....Resim
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

mrmarman yazdı:Şimdiye ........................lokasyon
Teşekkür ederim. Bu konuda oldukça ilerledim. Peki handle adresini bilgiğim bir resmi ve text'i nasıl kendi projeme alırım.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen mrmarman »

Bu ilerleme sanal bir ilerleme olmasın. :D Biraz hayal gücü ile çözerdin aslında. Çünkü ilerleme deyince Text'i gönderdiğini değerlendiriyorum.
- Aynı mantığı Resim için de uygulayamaz mıyız? diye sorsaydın keşke.
(1) Resmi bir yere kaydet,
(2) Resim linkini TEXT gönderir gibi gönder ve mesaj ile diğer projene bunu bildir. Mesaj için öncekinde WM_USER + 1234 demiştin ya, bu resim linki gönderme işine de (1) ekle WM_USER + 1235 olsun. Bu kanaldan gelen mesajları da resim linki olarak değerlendirirsin.
(3) Diğer projen mesaj gelince bu resmi alsın.
Resim
Resim ....Resim
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

Yok abi ne sanalı. Hatta veriyi direk sendmessage ile yolluyorum. Text falan uğraşmıyorum. Hatta yanılmıyorsam bu yöntemle listboxa item bile ekleniyor ama hala onu denemeye fırsatım olmadı.

Resim göndermeyi sormamın sebebi resim benim prpgramda değil. Başka bir programda. Başka programda hwnd bildiğimiz resmi nasıl alacaz. Ve stringi?
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen mrmarman »

Hocam bu başlıkta sorduğun soru çözüldü mü? EVET
Açılan başlık bir muhabbet kanalı olmadığına göre, hani nerede şöyle çözdüm deyip foruma mal edilecek cevap örnek kod? :wink:
Gelmeye çaşıştığım nokta soru nihayete kavuşmuşsa diğer konu için başka bir başlık oluştur. :)
Resim
Resim ....Resim
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen SimaWB »

:D

Kod: Tümünü seç

if (Hocam bu başlıkta sorduğun soru çözüldü mü = 'EVET') then
begin
  Burada kodları paylaş ki başkaları da faydalansın.
end;
:D
There's no place like 127.0.0.1
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

Kod: Tümünü seç

{ÖNCELİKLE}
Begin
:)
O kadar uğraştım ki başım döndü sonunda vardığım kanıya göre postmessage ve sendmessage aynı işe yaramıyor. Uzun stringler göndermek için sendmessage çok işe yarıyor.
En basit şekli aşağıdaki gibi,

Kod: Tümünü seç

sendmessage(HEDEF_HWND,wm_settext,length(edit2.Text),integer((edit2.Text)));
Yukarıdaki kodla uzuuun uzdıya stringler yolladım sorun yok.

Gelelim asıl hazineye. (XE2 için konuşuyorum)
ctrl tuşuna basılı tutarak wm_settext e tıkladığımızda winapi.messages.pas isimli dosyamızın ilgilendiğimiz konu ile ilgili bölümü karşımıza çıkıyor.
Burada tanımlı değişkenler ve yanlarındaki açıklamalar göz kamaştırıcı.
{ Listbox messages } diye başlayan bir kısım var. ve LB_ADDSTRING diye tanılanan birde değişken var. Daha neleeer neler var. Galiba bunları kullanarak text kutusuna metin eklediğimiz gibi listbox a da item ekleyebiliriz. Henüz kullanma ihtiyacı duymadım string göndermek işimi gördü ama ilerde mutlaka lazım olur diye bir kenara not aldım.

Tabi bu değişken adlarını bilmek yetmeyebilir. Kullanım şekilleri mutlaka farklılık gösterecektir.

Bu sayede daha önce birkaç yerde sorup cevabını alamadığım açık programa komut gönderme olayını da çözmüş oldum. Örneğin paint benzeri bir resim düzenleme yazılımımız olsun ve 2 kez açılmasını istemiyoruz. Program zaten açıkken bir resmi programa sadece çift tıklayarak veya birlikte aç diyerek yollayamıyordum. Bunu yapmak için program her açıldığında HWND sini aynı dizinde bir dosyaya yazar. Bir resme birlikte aç dediğinizde exe niz 2. kez açılacak komut olarak dosya yolunu alacak başka bir örneğin açık olduğunu tespit edince dosyaya kayıtlı hwnd bilgisi sayesinde açılmak istenen resmin yolu gönderilecek ve 2. örnek kapanacak. Resmin yolunu alan 1. örnek o resmi de yenş bir sekmede veya ihtiyaca uygun açacak.

Birde bizim olmayan programlardaki kontrollerin hwnd sini bulmak için de internetten rahatlıkla kodlar bulmak mümkün.

Gönderme işiniz çözdük ama alma işi hala yatıyor.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen mrmarman »

POSTMESSAGE konusunu yeniden değerlendirmen için örnek kod olarak aşağıdaki şekilde bir yapı paylaşayım.
Kendi kodların ile ilişki kurarak neler yapılabilir bir değerlendir.

Dinleyici projen için tanımlayıcı olsun diye formunun adını aşağıdaki gibi
DinleyiciForm koyduğunda Form Class adı da dolayısıyla TDinleyiciForm olacaktır. Bu cepte, çünkü göndereceğin metin için sana pencere bulma konusunda referans olacak.

Aşağıdaki kod ile bu forma bir tetik mekanizması kurulmuş olacak.

Kod: Tümünü seç

procedure TDinleyiciForm.FormCreate(Sender: TObject);
begin
  Application.OnMessage := MujdemiIsterim_MesajGeldi;
end;

procedure TDinleyiciForm.MujdemiIsterim_MesajGeldi(var Msg: TMsg; var Handled: Boolean);
Const
  WM_BenimMesajKanal = WM_USER + 1234; // Projemiz içindeki özel mesaj kanalımız
var
  wDepo : Word;
  strMesaj : String;
begin
  SetLength( strMesaj, 255 );
  if Msg.message = WM_BenimMesajKanal then
  begin
    wDepo := Msg.wParam; // deponun adresini aldık...
    GlobalGetAtomName(wDepo, PChar(strMesaj), 255); // depo edilen String'i okuduk.
    GlobalDeleteAtom (wDepo); // depoyu boşalttık.
    Handled := True;

    Memo1.Lines.Add( 'Mesaj: ' + strMesaj );
  end;
end;
TEXT gönderecek projende ise şöyle olsun.

Kod: Tümünü seç

procedure TForm1.BitBtn1Click(Sender: TObject);
Const
  WM_BenimMesajKanal = WM_USER + 1234;
Var
  aHandle : THandle;
  wDepo   : Word;
begin
  aHandle := FindWindow('TDinleyiciForm', 'DinleyiciForm');
  if aHandle <> 0 then
  begin
    wDepo := GlobalAddAtom( PChar( Edit1.Text ) ); // String'i depo ediyor ve bu yerin adresini wDepo'ya alıyoruz...
    PostMessage(aHandle, WM_BenimMesajKanal, wDepo, 0 ); // mesaj ile deponun adresini projemize yolluyoruz...
  end
  else MessageDlg('Proje aktif değil...'#13'Mesaj yollanamadı...', mtError, [mbOk], 0);
end;

Eğer 255 karakter bana yetmez dersen bunları paketler halinde arka arkaya yollayabilir, ya da daha önce dediğim şekilde HDD'de veya ağ altında bir yere tüm metni depo eder dosya adresini yollarsın.

Resimler için de benzerini yapabilirsin.
Resim
Resim ....Resim
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen SimaWB »

erkan1525 yazdı:

Kod: Tümünü seç

{ÖNCELİKLE}
Begin
:)
O kadar uğraştım ki başım döndü sonunda vardığım kanıya göre postmessage ve sendmessage aynı işe yaramıyor. Uzun stringler göndermek için sendmessage çok işe yarıyor.
En basit şekli aşağıdaki gibi,

Kod: Tümünü seç

sendmessage(HEDEF_HWND,wm_settext,length(edit2.Text),integer((edit2.Text)));
Yukarıdaki kodla uzuuun uzdıya stringler yolladım sorun yok.

Gelelim asıl hazineye. (XE2 için konuşuyorum)
ctrl tuşuna basılı tutarak wm_settext e tıkladığımızda winapi.messages.pas isimli dosyamızın ilgilendiğimiz konu ile ilgili bölümü karşımıza çıkıyor.
Burada tanımlı değişkenler ve yanlarındaki açıklamalar göz kamaştırıcı.
{ Listbox messages } diye başlayan bir kısım var. ve LB_ADDSTRING diye tanılanan birde değişken var. Daha neleeer neler var. Galiba bunları kullanarak text kutusuna metin eklediğimiz gibi listbox a da item ekleyebiliriz. Henüz kullanma ihtiyacı duymadım string göndermek işimi gördü ama ilerde mutlaka lazım olur diye bir kenara not aldım.

Tabi bu değişken adlarını bilmek yetmeyebilir. Kullanım şekilleri mutlaka farklılık gösterecektir.

Bu sayede daha önce birkaç yerde sorup cevabını alamadığım açık programa komut gönderme olayını da çözmüş oldum. Örneğin paint benzeri bir resim düzenleme yazılımımız olsun ve 2 kez açılmasını istemiyoruz. Program zaten açıkken bir resmi programa sadece çift tıklayarak veya birlikte aç diyerek yollayamıyordum. Bunu yapmak için program her açıldığında HWND sini aynı dizinde bir dosyaya yazar. Bir resme birlikte aç dediğinizde exe niz 2. kez açılacak komut olarak dosya yolunu alacak başka bir örneğin açık olduğunu tespit edince dosyaya kayıtlı hwnd bilgisi sayesinde açılmak istenen resmin yolu gönderilecek ve 2. örnek kapanacak. Resmin yolunu alan 1. örnek o resmi de yenş bir sekmede veya ihtiyaca uygun açacak.

Birde bizim olmayan programlardaki kontrollerin hwnd sini bulmak için de internetten rahatlıkla kodlar bulmak mümkün.

Gönderme işiniz çözdük ama alma işi hala yatıyor.
:bravo: :bravo: :bravo:
There's no place like 127.0.0.1
Kullanıcı avatarı
SimaWB
Üye
Mesajlar: 1316
Kayıt: 07 May 2009 10:42
Konum: İstanbul
İletişim:

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen SimaWB »

Yeri gelmişken PostMessage ve SendMessage hakkında kısa bilgi vereyim:
PostMessage asenkron, SendMessage ise senkron mesajlaşma biçimidir. PostMessage ile mesaj gönderdiğinizde programınız cevap beklemeden yoluna devam eder. Ama SendMessage ile gönderirseniz gönderdiğiniz taraftan cevap gelmeden programınız bir sonraki satıra geçmez. Yani cevap bekler.
IPC size karmaşık geldiyse bunu kullanabilirsiniz. Örneklerinde de görürsünüz, client yada server tarafı çok kolay hazırlayabilirsiniz. Ayrıca thread safe'tir.
There's no place like 127.0.0.1
erkan1525
Üye
Mesajlar: 113
Kayıt: 12 Ağu 2014 01:31

Re: IPC'nin içinden çıkamadım.

Mesaj gönderen erkan1525 »

ama post message ile sadece 1 karakter gidiyor?
Cevapla