zoukankan      html  css  js  c++  java
  • Clipboard with Custom Clipboard Formats Delphi

    http://delphi.about.com/od/windowsshellapi/a/clipboard_spy_3.htm

    Do you know that, for example, MS Word has it's own format for storing data to the clipboard?
    Large number of applications paste information in other formats, for example Rich Text Format, HTML format and so forth.
    Why not use Delphi to create and store our specific formats (like records) in the clipboard.
    This can be very useful in moving data between two Delphi applications.
    Let's say we have a record type called TMember, declared as:

     type
       TMember = record
         Name : string;
         eMail : string;
         Posts : Cardinal;
       end; 

    We want to paste a variable of TMember type to the clipboard.
    Before we can write information to the clipboard in a specific format, the format must be registered.
    We register a new clipboard format by calling the RegisterClipboardFormat API function and
    specifying a unique name for your new format - this enables us to copy and paste any type of data we want.

    First we have to register the CF_TMember format (that holds TMember type variable values),
    in the OnCreate procedure of the main form, so that we can use it later on during clipboard calls.
    Newly created clipboard format will be named:
    'OurFormat' and it will hold data from DelphiGuide variable filled in the OnCreate event and declared at the form level.

    Then we send our data to the clipboard.

    Sending custom format data to the clipboard is coded in the following way:

    1. Open the clipboard with OpenClipboard.
    2. Empty current contents of the clipboard with EmptyClipboard.
    3. Allocate and lock a global memory block.
    4. Copy data into the global memory block.
    5. Unlock the block.
    6. Transfer the block to the Clipboard with SetClipboardData. (Windows now controls the block).
    7. Close the clipboard with CloseClipboard. (So other programs can access it).
     var DelphiGuide: TMember;
     ...
         MemberPointer : ^TMember;
         MemberHandle : HGLOBAL;
     ...
      //fill some dummy data
      DelphiGuide.Name := 'Zarko Gajic';
      DelphiGuide.eMail := 'delphi@aboutguide.com';
      DelphiGuide.Posts := 15;
     
      OurFormat := RegisterClipboardFormat('CF_TMember') ;
     
      if OpenClipboard(Handle) then
      begin
        EmptyClipboard;
     
        MemberHandle := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE, SizeOf(TMember)) ;
        MemberPointer := GlobalLock(MemberHandle) ;
     
        MemberPointer^.Name := DelphiGuide.Name;
        MemberPointer^.eMail := DelphiGuide.eMail;
        MemberPointer^.Posts := DelphiGuide.Posts;
     
        GlobalUnLock(MemberHandle) ;
        SetClipboardData(OurFormat,MemberHandle) ;
        CloseClipboard() ;
      end; 

    Again, to act whenever the contents of the clipboard changes we need to respond to a WM_DrawClipboard message.
    We use the HasFormat function to find out whether the clipboard contains data encoded in a specific format.

    Getting custom format data from the clipboard is coded in the following way:

    1. Open the clipboard with OpenClipboard.
    2. Get a handle to the clipboard data with GetClipboardData.
    3. Allocate and lock a memory block to hold the clipboard data.
    4. Lock the clipboard data block.
    5. Copy data from the clipboard data block to the program's data block
      (The data can now be manipulated by the application).
    6. Unlock both memory blocks.
    7. Close the clipboard with CloseClipboard.
     if Clipboard.HasFormat(OurFormat) then
     begin
      if OpenClipboard(Handle) then
      begin
       MemberInClip := GetClipboardData(OurFormat) ;
       MemberPointer := GlobalLock(MemberInClip) ;
       with AMember do
       begin
        Name := MemberPointer^.Name;
        eMail := MemberPointer^.eMail;
        Posts := MemberPointer^.Posts;
       end;
       GlobalUnLock(MemberInClip) ;
       CloseClipboard() ;
       with Memo1.Lines do
       begin
        Clear;
        Add('Clipboard has TMember data:') ;
        Add(AMember.Name) ;
        Add(AMember.email) ;
        Add(IntToStr(AMember.Posts)) ;
       end;
      end;
     end; 

    Note:
    in normal situation we'll have one Delphi application sending data to the clipboard and another Delphi application getting data from it.
    Since this is the demo project we have only one application running - we send custom formatted data to the clipboard
    in the OnCreate event for the form. In the same form, we are handling the clipboard change notification, therefore when we start our project, Memo1 component is filled with data from the clipboard - i.e. the data we are sending when the form is created.

    Are You in Control Now?

    That's it. We have the clipboard working just as we would like it to.
    No one can send data to the clipboard without us knowing that something is going on.
    Even more: we can copy and paste program-specific data to the clipboard.
    However, some questions stay unanswered:
    What is the best way of sending an array of TMember variables to another Delphi application;
    what will happen if some other application is register 'CF_TMember' with some other format, and so on.


  • 相关阅读:
    Windows下安装tesserocr
    Python中的那些“坑”
    【Python3爬虫】用Python中的队列来写爬虫
    【Python3爬虫】常见反爬虫措施及解决办法(三)
    【Python3爬虫】常见反爬虫措施及解决办法(二)
    【Python3爬虫】常见反爬虫措施及解决办法(一)
    【Python3爬虫】教你怎么利用免费代理搭建代理池
    【Python3爬虫】自动查询天气并实现语音播报
    【Python3爬虫】百度一下,坑死你?
    【Python3爬虫】为什么你的博客没人看呢?
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3056441.html
Copyright © 2011-2022 走看看