Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Clipboard > Png
#11
(21-12-2016, Saat: 10:53)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.İhtiyacı olabilecek arkadaşların benim gibi sıkıntı yaşamaması adına yazdığım kodu beğeninize sunuyorum:

function GetPNGImageFromClipboard : TGraphic;
var
 APngRegisterFormat  : Word;
 AClipboardData      : NativeUInt;
 ADataPointer        : PByte;
 ADataSize           : NativeUInt;
 APureData           : TBytes;
 ADataStream         : TBytesStream;
begin
 Result := nil;

 APngRegisterFormat := RegisterClipboardFormat('PNG');

 if APngRegisterFormat = 0 then
   Exit;

 if OpenClipboard(0) then
 begin
   try
     if IsClipboardFormatAvailable(APngRegisterFormat) then
     begin
       AClipboardData := GetClipboardData( APngRegisterFormat );

       if AClipboardData <> 0 then
       begin
         ADataPointer := GlobalLock( AClipboardData );

         if Assigned(ADataPointer) then
         begin
           try
             ADataSize := GlobalSize( AClipboardData );

             if ADataSize <> 0 then
             begin
               SetLength(APureData, ADataSize);
               Move(ADataPointer^, APureData[0], ADataSize);

               ADataStream := TBytesStream.Create(APureData);

               try
                 ADataStream.Position := 0;

                 Result := TPngImage.Create;

                 Result.LoadFromStream(ADataStream);
               finally
                 FreeAndNil(ADataStream);
                 APureData := nil;
               end; // try..finally
             end; // if ADataSize <> 0 then
           finally
             GlobalUnlock( AClipboardData );
           end; // try..finally
         end; // if Assigned(ADataPointer) then
       end; // if AClipboardData <> 0 then
     end; // if IsClipboardFormatAvailable(APngRegisterFormat) then
   finally
     CloseClipboard;
   end; // try..finally
 end; // if OpenClipboard(0) then
end;

Tuğrul hocam müsadenizle yorum satırlarını uçurarak fonksiyonu daha düz hale çevirdim.
function GetPNGImageFromClipboard: TGraphic;
var
 APngRegisterFormat: Word;
 AClipboardData: NativeUInt;
 ADataPointer: PByte;
 ADataSize: NativeUInt;
 APureData: TBytes;
 ADataStream: TBytesStream;
begin
 Result := nil;

 APngRegisterFormat := RegisterClipboardFormat('PNG');

 if APngRegisterFormat = 0 then
   Exit;

 if not IsClipboardFormatAvailable(APngRegisterFormat) then
   Exit;

 if not OpenClipboard(0) then
   Exit;

 AClipboardData := GetClipboardData(APngRegisterFormat);
 if AClipboardData = 0 then
 begin
   CloseClipboard;
   Exit;
 end;

 ADataPointer := GlobalLock(AClipboardData);
 if not Assigned(ADataPointer) then
 begin
   CloseClipboard;
   Exit;
 end;

 ADataSize := GlobalSize(AClipboardData);
 if ADataSize = 0 then
 begin
   GlobalUnlock(AClipboardData);
   CloseClipboard;
   Exit;
 end;

 try
   SetLength(APureData, ADataSize);
   Move(ADataPointer^, APureData[0], ADataSize);
   ADataStream := TBytesStream.Create(APureData);
   ADataStream.Position := 0;

   Result := TPngImage.Create;
   Result.LoadFromStream(ADataStream);
 finally
   FreeAndNil(ADataStream);
   APureData := nil;
 end;

 GlobalUnlock(AClipboardData);
 CloseClipboard;
end;


Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. word'e atıp denediğimde bende de çalıştı.
One of the major software engineering challanges is managing change.
Cevapla
#12
(21-12-2016, Saat: 21:57)kimimben Adlı Kullanıcıdan Alıntı: 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. word'e atıp denediğimde bende de çalıştı.


Örnek fotoğraf harika Big Grin
There's no place like 127.0.0.1
WWW
Cevapla
#13
Merhaba,
Sonunda bende çalışmama nedenini buldum!
İpucunu @kimimben yazmış olduğu;

(21-12-2016, Saat: 21:57)kimimben Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. word'e atıp denediğimde bende de çalıştı.

kelimesinden yakalayıp, yola çıkarak buldum. Tabi buluş Tuğrul hocamın yazmış olduğu fonksiyonda bir revizyona neden olabilir.  Smile

Denediğim yöntemler;
1- Herhangi bir resmi Windows gezgininde kopyalamada,
2- Herhangi bir resmi, herhangi bir resim editörü (testler; Paint, FireWorks, Windows resim gösterici, Snagit resim editörü) ile açıp kopyalamada,
3- Resmin kopyalanıp önce Word'e yapıştırılması, daha sonra buradan kopyalanması durumunda,
4- Word'e  Ekle > Resimler menüsü yardımıyla bir resim ekleyerek, kopyalanması durumunda,

GetPNGImageFromClipboard metodunda;

Image1.Picture.Assign(GetPNGImageFromClipboard);

şeklinde Assign edilen Image1'in Picture özelliği, IsClipboardFormatAvailable(APngRegisterFormat)  fonksiyonun false değer döndürmesi sonucunda, işlem görmüyor.

Yalnızca Word açık iken, Windows gezgininden Word üzerine sürükleyip bıraktığım bir resmi kopyaladığımda metod beklenen doğrultuda çalıştı.

Test edilen ortam
OS: 64 bit- Win 10 Pro
Delphi : Berlin 10.1.2 (24.0.25048.9432)
Office:  2016 (1610 - 7466.2038)

Örnek çalışma
30t51yq.jpg
While true do; Hayat döngüsü, kısır değildir! Yapılan bir yanlış, o döngünün dışına çıkmanızı sağlayacaktır.
WWW
Cevapla
#14
Paylaştığım metodun çalışabilmesi için clipboard'da saf PNG datası olması gerekiyor. Bir PNG dosyayı kopyalamak clipboard'da FILE bilgisinin olmasına neden olur. Bu sebep ile, PNG dosyayı herhangi bir editörde açıp, saf PNG datasının clipboard'a gönderilmesini sağlamalısınız. O anda clipboard'da ne olduğunu görebilmek için aşağıdaki test metodunu kullanabilirsiniz.

procedure TForm1.EnumClipboard;
var
 AFormat      : Word;
 AFormatName : array[0..1023] of Char;
begin
 OpenClipboard(0);

 try
   AFormat := EnumClipboardFormats(0);

   while AFormat <> 0 do
   begin
     GetClipboardFormatName(AFormat, AFormatName, 1024);
     Memo1.Lines.Add(AFormatName);

     AFormat := EnumClipboardFormats(AFormat);
   end;
 finally
   CloseClipboard;
 end;
end;

Clipboard'a kopyaladığınız png bilgisinden sonra yukarıdaki kod örneğini çalıştırırsanız size clipboard'daki format hakkında bilgi verecektir. Eğer PNG görüyorsanız ilgili memo'da bu durumda daha önce paylaştığım GetPNGImageFromClipboard metodu düzgün bir şekilde çalışabilecektir.

Ayrıca belirtmek isterim ki; her resim editörü dosyanın formatı PNG olsa da alpha desteklemeyebiliyor, dolayısı ile clipboard'a resmi alpha formatından yoksun Bitmap formatında atabiliyor. Bunun için Gimp denemenizi önerebilirim.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#15
Detaylı bilgilendirme için teşekkür ederim hocam.
While true do; Hayat döngüsü, kısır değildir! Yapılan bir yanlış, o döngünün dışına çıkmanızı sağlayacaktır.
WWW
Cevapla
#16
Clipboard'daki formatlar için Vcl.Clipbrd.TClipboard sınıfının hazır özellikleri mevcut. 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.. Ayrıca Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. özelliği ile de Clipboard'da aranan formatta veri olup olmadığı kontrol edilebilir.
There's no place like 127.0.0.1
WWW
Cevapla
#17
(22-12-2016, Saat: 11:57)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Clipboard'daki formatlar için Vcl.Clipbrd.TClipboard sınıfının hazır özellikleri mevcut. 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.. Ayrıca Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız. özelliği ile de Clipboard'da aranan formatta veri olup olmadığı kontrol edilebilir.

Onlar da altyapısında benim sizinle paylaştığım API'leri kullanıyorlar zaten üstad Wink
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#18
Evet, biliyorum ama Delphi RTL içine alınmış çözümleri kullanmaya gayret ediyorum. Sizin mantığınıza ters biliyorum ama Big Grin  RTL içinde var olanı yeniden yazmak hoşuma gitmiyor.
Elbette TClipboard.Formats nedir, ne yapar araştırırım ama RTL içinde varsa ve tam olarak benim yapmak istediğimi yapıyorsa onu kullanırım. Daha güvenli görüyorum.

Bu arada; asıl amaç Word belgesi içindeki resmi almaktı sanırım. Ben de ufacık bir katkı yapayım, belki sonra birinin işine yarar...

Aşağıdaki kod örneği Word belgesi içindeki ilk resmi (PNG olduğunu varsayıyoruz) Image1'e atar.


var
 WordApp, Doc, Img: Variant;
begin
 WordApp := CreateOleObject('Word.Application');
 try
   WordApp.Visible := False;
   Doc := WordApp.Documents.Open('C:\Belge.docx');
   Img := WordApp.ActiveDocument.InlineShapes.Item(1);
   Img.Range.Copy;
   Image1.Picture.Assign(GetPNGImageFromClipboard);
 finally
   WordApp.Quit;
 end;
end;
There's no place like 127.0.0.1
WWW
Cevapla
#19
Merhaba.

Clipboard'a Word'den okumayı yapmışsınız, stream aktarmayı da, eksik kalmasın diye bir de (PNG) dosyanın bir File Explorer üzerinden, dosyanın kendisinin bizatihi copy / paste yapılıp yapılmadığını test için de aşağıdaki şekilde clipboard içindeki dosyalardan tekil ve PNG dosya uzantılı olup olmadığı sorgulanıp, standart loadfromfile ile elde etmek için olan fonksiyonu da ekleyeyim eksik kalmasın.

EK: Genel için yazayım, aşağıdaki fonksiyon sadece ClipBoard'daki dosya isimlerini alan kısmı örneklemek içindir. Bu dosya isimlerinin listeden alınarak gerçekten PNG mi olup olmadığı önce uzantısına bakılarak ardından da Try/Except bloğu ile LoadFrom File ile ele alınacaktır.  

uses Clipbrd, ShellApi;

procedure ClipboardDosya_lar( Dosyalar: TStrings);
var
  hDropHandle : ShellApi.HDROP;
  szBuffer    : PChar;
  iSay, iIdx  : Integer;
  iDosyaUz: Integer;
begin
  // Create edilmemiş TStrings için ön kontrol
  if (Dosyalar = nil) then Exit;
  Dosyalar.Clear;
  // Clipboard'ı işimiz bitene kadar meşgule alalım
  Clipboard.Open;
  try
  // Clipboard'da dosya var mı ?
  if (Clipboard.HasFormat(CF_HDROP)) then
  begin
    // var demektir, bunların Drop Handle'larını alalım
    hDropHandle := Clipboard.GetAsHandle(CF_HDROP);
    // Dosya Kaç dosya var ? iSay'a alalım
    iSay := DragQueryFile(hDropHandle, $FFFFFFFF, nil, 0);
    // Döngü ile bunları bir bir Listeye alalım...
    for iIdx := 0 to iSay - 1 do
    begin
      // Önce dosya uzunluğu
      iDosyaUz := DragQueryFile(hDropHandle, iIdx, nil, 0);
      // Memory bloğunu rezerve edelim, "iDosyaUz" için #0'a ilişkin (+1) ekliyouz.
      szBuffer := StrAlloc(iDosyaUz + 1);
      try
      // Dosya Adını Alıyoruz...
      DragQueryFile(hDropHandle, iIdx, szBuffer, iDosyaUz + 1);
      Dosyalar.Add(szBuffer);
      finally // Memory Dispose ederek serbest bırakıyoruz.
        StrDispose(szBuffer);
      end;
    end;
  end;
  finally
    // Clipboard'ı serbest bırakalım.
    Clipboard.Close;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  Liste : TStringList;
begin
   Liste := TStringList.Create;
   ClipboardDosya_lar( Liste );
   ShowMessage( Liste.Text );
   Liste.Free;
end;

Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif


Cevapla




Konuyu Okuyanlar: 1 Ziyaretçi