             31 

       Windows API 

      

    --      
        Windows    
     Windows API. 
    --             ; 
          ,   Windows API.           ''. 
    --  32-  
       32    Delphi. 
    --    
       
        
    Windows API. 
    --         ,      
          ,   
         . 

      ,    ,    ,  640 
      ,    
 ,        . 
          DOS    
     ,     ,   
. ,     256     
    .    ,    
Windows     ...     
,           (  
     )       
 ,   , ,   ..   
    Windows. 
       Windows     , 
     ,   . 
,  MORICONS . DLL   Windows   
 DLL,    ( ).  
DLL     Windows   ,    
   ,   DRV 
(), FON ()    (      
 ). 
    ,  DLL.    
 .  ,       
,     ,  ,   
  . 
        ,  DLL    
.    ,      
,      .   
   
    716 

   ,    DLL 
  -.  DLL      
     (plug-ins). 
           Windows API,  
  DLL,    Windows     
 . 

         

      Delphi      Windows API 
   , ,    , 
   WINDOWS . PAS   Delphi.    
      , : 

    var NumTicks: Longint; 
    begin 
    NumTicks := GetTickCount; 
    end; 

         Windows API GetTickCount,  
     Windows. ,   Delphi  
     24 ,   Delphi  
  32-       49  
  Windows   32-   0.   
     " 32- "  . 
      DLL,     ,   
  (static linking).    
  DLL    ,        
  .   Windows . ,   
 GetTickCount (). 

    unit Windows; 
    interface 
    type DWORD = Integer
    function GetTickCount: DWORD; stdcall; 
    implementation 
    function GetTickCount; external 'kernel32.dll' name 'GetTickCount'; 
    end. 

         GetTickCount:   
   stdcall    DLL- kernel32.  
  ,         
 .       
,   DLL     ,   
,    WINDOWS, \WINDOWS\SYSTEM   ,   
  path.  DLL   ,   . 
         ,   : 

    function GetTimerTicks; external 'kernel32.dll' name 'GetTickCount'; 

            GetTimerTicks,  
    GetTickCount   kernel32.   
  (remapping)       
Windows. ,  IstrlenO  Windows      
ANSI   ,   ,     
  .     Windows    
   . 

    function IstrlenA; external 'kernel32' name 'IstrlenA'; 
    function IstrlenW; external 'kernel32' name 'IstrlenW'; 
    function Istrlen; external 'kernel32' name 'IstrlenA'; 

         Istrlen  Delphi  
 ANSI-.    Delphi,    
  ,       
 IstrlenA  IstrlenW (      
   ). 

     31.    Windows API                            717 

    ,        
 ,   ,     
     .     
    . 

    procedure SomeProc(1: Longint); 
    {$IFDEF Win32} stdcall; {$ELSE} far; {$ENDIF} external 'TESTDLL' index 1; 

     ,       16-,    
32-,  Delphi     
.        ,    
 (ordinal} DLL. '    
,   ,        
,        DLL. 
            
,         DLL.  
      ,  DLL  
  ,       ,  , 
        
.       DLL  , 
     "^" .  DLL 
  ,     . 
       ,      
   .     ,  
      .    
      DLL  
^^ GetPlugInEffectName ().   , 
  DLL     ( )  
 .    4),  ,   
 DLL  ,      DLL   
 ApplyEffect (),   DLL . 
        DLL,   ,  
,   DLL   . 

    {$IFDEF Win32} 
    const BadDllLoad = 0; 
    ($ELSE} 
    const BadDllLoad = 32; 
    {$ENDIF} 
    procedure DoEffect(TheBitmap: HBitmap; 
    DllName: pChar); 
    var 
    DllHandle : THandle; 
    EffectProc : procedure(TheBitmap: HBitmap); 
    ($IFDEF Win32) stdcall; ($ENDIF) begin 
    DllHandle := LoadLibrary(DllName); 
    if DllHandle >= BadDllLoad then begin 
    @EffectProc := GetProcAddress(DllHandle, 'ApplyEffect'); 
    if @EffectProc <> nil then EffectProc(TheBitmap); 
    FreeLibrary(DllHandle) ; 
    end; 
    end; 

             , 
  16-  32-  Delphi.    
 DLL DllHandle    EffectProc.  DLL  
,     ApplyEffect     
EffectProc.   ,  ,    DLL  . 
     ,        
  ,       . 

       

     ,            
    DLL    ,  ,    
30, " Delphi  C++".    ,  
   ,        
     .      
.                 -

    718                                        VI.   

             
32-     stdcall,     
  16-    pascal-  
. Delphi      ,   
  Windows (16     
  pascal  cdecl). 
        . 

    cdecl 
         ,     
  . :       
 . 

    pascal 
         ,    
  . :  20% ,  cdecl. 

    stdcall 
         ,    
  .     cdecl  
pascal.       " 

    register 
       fastcall.      
     CPU , EDX  ,  
     .     
 . :    pascal  
       . 
           . 
    ,  32-  Windows    
 stdcall,  32-  Delphi    
 register.   16-       pascal. 

    safecall 
     ,    stdcall,       try/except  
  OLE. 

       

        ,   
  .   ,  Borland 
       (ST (0)),   
  Microsoft      
.  ,    DLL    
  -. 

     WINDOWS.PAS 

     , , ,   ,   Windows 
API, ,      .  
    ,  -    .   
  Delphi    VCL ( \SOURCE\RTL\WIN), 
    ,      . 
      ,   
 (            
Options  RTL\WIN)         
 ,    .    , 
          . 
  ,        
Windows API   DLL,      . ,  
          ,    
 "     ,   .  
     16-  32-   . 
    ,         
       .   
  ,         
VCL.          VCL,   
   VCL.      - 
 (,     ,    ), 
 ,   ,     ,    
 -    .                  

     31.    Windows API                            719 

    ,  GetSystemPaletteEntries ()      
 ,          
,    .   . 

    function GetSystemPaletteEntries(DC:,HDC; 
    ;')   Startlndex, NumEn tries': UINT; 
     var PaletteEntries) : UI'NT; stdcall; 

     ,   , PaletteEntries,  
  .  ,      
   (     ).  
,           
.     ,   , , 
   .        
   ,    . 

    function GetSystemPaletteEntries(DC: ; 
    Startlndex, NumEntries: UINT; 
    PaletteEntries: pointer): UINT; 
    ($IFDEF Win32} stdcall; ($ELSE) far; {$ENDIF} external 'gdi32.dll' name 'GetSystemPaletteEntries'; 
                . 
    procedure TFormI.ButtonlClick(Sender: TObject) ; 
    var 
    dc: hdc ; 
    p : pointer; 
    begin 
    dc := GetDc(0) ; 
    GetMemfp, 256*sizeof(TPaletteEntry) ); 
    GetSystemPaletteEntries(dc,0,256,p) ; 
    ( -    ) 
    FreeMem(p, 256*sizeof(TPaletteEntry)) ; 
    ReleaseDc(O.dc); 
    end; 

     :         Windows, 
     Borland (   ,   Web-). 

     32-  

        ,  Delphi     
32-   .    -,  
   .    32-  
   (double)    ,    
 .   ,       
 ,     . 
          ,  
 longint  double  .    
longint   double  , ,   
 longint   -2147483648  2147483647,     
 0  4294967295. 

    ($IFOPT Q+} 
    {$DEFINE CKOVERFLOW} 
    <$Q-} ($ENDIF) 
    function UlntToDouble(u: longint): double; 
    var 
    d : double; 
    begin 
    if u >= 0 then 
    d := u else 
    if u=-l then b,egin 
    d := $7FFFFFFF; 
    d := d+d+1; 
    end else begin 
    d := $7FFFFFFF; 
    d := d+abs($7FFFFFFF - u) ; 
    end; 


    720                                        VI.   


    result :" d; 
    end; 
    function DoubleToUInt(d: double): longint; 
    var 
    n : double; 
    begin 
    if d<0 then d := Abs; 
    d := Int; 
    n := $7FFFFFFF; 
    n := n+n+2; 
    while d>=n do d := d~n; 
    if d= (n-1) then 
    result :== -1 
    else if d > $7FFFFFFF then 
    result := not ($80000000 - trunc(d-$7FFFFFFF) ) 
    else 
    result := Trunc; 
    end; 
    ($IFDEF CKOVERFLOW} 
    ($UNDEF CKOVERFLOW} 
    {$Q+} 
    {$ENDIF} 
    procedure TFormI.ButtonlClick(Sender: TObject); 
    var 
    NumTicks : longint; 
    RealNumTicks : double; 
    begin 
    {NumTicks    .} 
    NumTicks := GetTickCount; 
    (    .} 
    RealNumTicks := UlntToDouble(NumTicks); 
    { .} 
    NumTicks := DoubleToUInt(RealNumTicks); 
    end; 

              $IFOPT 
 $IFDEF.      (  )  
      ,     
   .    ,  ,  
$7FFPFFFF    longint.   
  (,          
   ).  ,      
  ,        
,     . 

       

       (Callback functions)      
   Windows.     ,  
 ,       ,   
   ,   ,    
 . 
            
 . ,     ,  
,          
.   ,       
      .       
           
   .        
   true,      ,  false 
  . 
    ,   ,      
 Windows,   "  ".   
 Iparam    32- ,  
 (     ).    
    

     31.    Windows API                            721 

 ,    .    
,  ,      -    . 
    ,          
   .        
  ,          
 .           
  Iparam     Windows.   
 . 

    function FillFontList(Ipelf : PEnumLogFont; 
    Ipntm : PNewTextMetric; 
    FontType: integer; 
    Param : pointer) : integer 
    {$IFDEF Win32) stdcall; {$ELSE} ; export; ($ENDIF) 
    begin 
    TListBox(param^).Items.Add(Ipelf.elfLogFont.IfFaceName) ; 
    FillFontList := 1; 
    end; 
    procedure TFormI.ButtonlClick(Sender: TObject); 
    var 
    dc : hdc ; 
    fn : pointer; 
    begin 
    dc := GetDc(O) ; 
    fn := MakeProdnstance (QFillFontList, hinstance); 
    EnumFontFamilies(dc, fn, 
    ($IFDEF Win32) 
    longint(@ListBoxl)) ; 
    ($ELSE) 
    OListBoxl) ; 
    {$ENDIF} 
    FreeProcInstance(fn); 
    ReleaseDc(0,dc) ; 
    end; 

            FillFontList. 
   ,        16-,   
 32-  Windows.      Param 
  ,         
1 (True),   Windows,     . 
      ButtonlClick     hdc  pointer,  
  Dc       
FillFontList ()   Windows MakeProcInstance (   
32-^  (     ),   
  DLL      
,    16-     ...). , , 
   EnumFontFamilies (),      dc, 
    ,  ,   
,      , -.    
     .  32-   
   longint"       
  16- .       
     dc. 

      

     (hook , .  . .)    
 ,     Windows    
  ,     .    
    DOS.   ,    
, ,      ,   
    ,       
  (    - ).          
            Windows 
SetWindowsHook (),   32- ,   
  .      'Windows,  
  32    32-,    16-  . 
         
 CallNextHookEx () (,        
 ,   ).  ,     
,   ,       
    UnHookWindowsHookEx (). , 
       32-,   16-  Windows. 

    722                                        VI.   


     Windows 

    Windows    . 

    WH.CALLWNDPROC 
         SendMessage () . 

    WH.CALLWNDPROCRET 
          SendMessage ().  
  Windows 95. 

    WH_CBT 
       , , , 
, ,      , 
   ,     , 
       . 

    WH.DEBUG 
          . 

    WH.GETMESSAGE 
             
 GetMessage (). 

    WH.HARDWARE 
           GetMessage 
()  PeekMessage ()      ( 
  ). 

    WH.JOURNALRECORD 
            
  . 

    WH.JOURNALPLAYBACK 
            
   . 

    WH.KEYBOARD 
          GetMessage ()  
PeekMessage ()   WM_KEYDOWN  WM_KEYUP. 

    WH.MOUSE 
          GetMessage ()  
PeekMessage ()   . 

    WH.MSGFILTER 
           
 ,    ,    . 

    WH.SHELL 
            
 . 

    WH.SYSMSGFILTER 
           
 ,    ,    . 


        

            
  ,    DLL,        
    DLL.  ,    
Windows             
 Windows. - .      Microsoft's 
KnowledgeBase  - MSDN.   ,    
   ,  <Ctrl+Alt+Del>;      
  . 

     31.    Windows API                            723 


             

          Windows,   
             
    . ,       
         ( ,  
SendMessage ()       ).   
 Windows,      ,  ,  
   .      , 
  JournalPlayback   Windows  ,  
   .  DLL     
   .       
16- ,     32-,      
    . 
      ,  ,   
"".      ,   
        .  
          
  ( ).      
 . 

    CreateMsgBuff           
    Is Playing              "" 
    AddKeyString              
    AddMouseMessage        
    AddVkMessage             
    AddVkMsgPair          KeyUp/KeyDown 
    PlayMouseKeys       ""    
    DeleteMsgBuff          

      PLAYKEYS . DPR    . 
  31.1    PLAYKEYS . DLL. 
    
     31.1. \UDELPHI3\CHP31\BAREBONES.DPR                                
                       :| 
    {$ FIXED PRELOAD PERMANENT) 
    library PLAYKEYS; 
    ($IFDEF Win32} 
    uses Windows, Messages; 
    type 
    TwMessage = Longint; 
    TwParameter = Longint; 
    TIParameter = Longint; 
    {$ELSE} 
    uses WinTypes, WinProcs, Messages; 
    type 
    TwMessage = Word; 
    TwParameter = Word; 
    TIParameter = Longint; 
    {$ENDIF) 
    type PMsgItem = ^TMsgItem; 
    TMsgItem = record 
    Event : TEventMsg; 
    Next : PMsgItem; 
    end; 
    type PMsgHeader = ^TMsgHeader; 
    TMsgHeader = record 
    First : PMsgItem; 


    724                                        VI.   


    Last : PMsgItem; 
    end; 
    var 
    Playing  : LongBool; 
    IpMsg   : pMsgItem; 
    HookHandle : HHook; 
    function PlaybackProc(Code: Integer; 
    wParam: TwParameter; 
    IParam: TIParameter): Longint; 
    {$IFDEF Win32) stdcall; {$ELSE} export; ($ENDIF} 
    begin 
    PlaybackProc := 0; 
    case Code of 
    HC_SKIP : begin 
    {fetch the next message} 
    IpMsg := IpMsg".Next; 
    {are we done?} 
    if IpMsg = nil then 
    if UnHookWindowsHookEx(HookHandle) then 
    Playing := false; 
    exit; 
    end; 
    HC_GETNEXT : begin 
    {play the current message) 
    PEventMsg(IParam)" := IpMsg^.Event; 
    PEventMsg(IParam)/\ .Time := GetTickCount; 
    exit; 
    end; 
    HC_SYSMODALON : begin 
    {system error - let the next hook know about it} 
    CallNextHookEx(HookHandle, Code, wParam, IParam); 
    exit; 
    end; 
    HC_SYSMODALOFF : begin 
    {system error - let the next hook know about it} 
    {note : our hook has been canceled by the system} 
    CallNextHookEx(HookHandle, Code, wParam, IParam); 
    exit; 
    end; 
    end; 
    {request to call the next hook} 
    if code < 0 then 
    PlaybackProc := CallNextHookEx(HookHandle, Code, wParam, IParam); 
    end; 
    function PlayMouseKeys(IpMessages : PMsgHeader): LongBool; 
    {$IFDEF Win32) stdcall; {$ELSE} export; {$ENDIF) begin 
    PlayMouseKeys := false; 
    {avoid data segement corruption} 
    if Playing then exit; 
    Playing := true; 


     31.    Windows API                            725 


    (is the buffer a valid pointer?) 
    if IpMessages = nil then begin 
    Playing := false; 
    exit; 
    end; 
    {are there messages to play?} 
    if IpMessages".First = nil then begin 
    Playing := false; 
    exit; 
    end; 
    {get the first message) 
    IpMsg := IpMessages".First; 
    {set the hook} 
    HookHandle := SetWindowsHookEx(WH_JOURNALPLAYBACK, 
    PlayBackProc,  ~-""""''' 
    hinstance, 
    0); 
    {was there an error setting the hook?} 
    if HookHandle = 0 then begin 
    Playing := false; 
    exit; 
    end; 
    {everything is ok!} 
    PlayMouseKeys := true; 
    end; 
    function IsPlaying : LongBool; 
    ($IFDEF Win32) stdcall; ($ELSE) export; {$ENDIF} 
    begin 
    IsPlaying := Playing; 
    end; 
    procedure CreateMsgBuff(var IpMessages : PMsgHeader); 
    {$IFDEF Win32) stdcall; ($ELSE) export; {$ENDIF} 
    begin 
    {create and the message buffer } 
    GetMem'(lpMessages, sizeof(TMsgHeader)) ; 
    {Was there an error?} 
    if IpMessages = nil then exit; 
    {initialize the message buffer} 
    IpMessages".First := nil; 
    IpMessages".Last := nil; 
    end; 
    procedure DeleteMsgBuff(var IpMessages : PMsgHeader); 
    {$IFDEF Win32} stdcall; {$ELSE} export; {$ENDIF) 
    var 
    Next : PMsgItem; 
    Temp : PMsgItem; 
    begin 
    {is the buffer pointer valid?} 
    if IpMessages = nil then exit; 
    {loop though buffer and destory items} 
    Next := IpMessages".First; 
    while Next <> nil do begin 
    Temp := Next".Next; 
    FreeMem(Next, sizeof(TMsgItem)) ; 


    726                                        VI.   


    Next := Temp; 
    end; 
    {destroy the header record) 
    FreeMem(lpMessages, sizeof(TMsgHeader)); 
    {invalidate the message buffer) 
    IpMessages := nil; 
    end; 
    procedure CreateNextMsgItem(lpMessages : PMsgHeader) ; 
    begin             " 
    (is the buffer pointer valid?) 
    if IpMessages = nil then exit; 
    {is this the first item?) 
    if IpMessages".First = nil then begin 
    GetMemdpMessages" . First, sizeof (TMsgItem) ) ; 
    IpMessages".Last := IpMessages".First; 
    end else begin 
    GetMem(IpMessages".Last".Next, sizeof(TMsgItem)) ; 
    IpMessages".Last := IpMessages".Last".Next; 
    end; 
    (was there an error?) 
    if IpMessages".Last = nil then exit; 
    {initialize the new item with zeros) 
    FillChar(lpMessages".Last", sizeof(TMsgItem), #0); 
    end; 
    function AddVkMessage(IpMessages : PMsgHeader; 
    TheMsg : Word; 
    TheVkKey : Word) : LongBool; 
    ($IFDEF Win32) stdcall; {$ELSE} export; ($ENDIF) 
    begin 
    AddVkMessage := false; 
    (is the buffer pointer valid?) 
    if IpMessages = nil then exit; 
    {create a new message item) 
    CreateNextMsgItem(lpMessages) ; 
    {was there an error?) 
    if IpMessages".Last = nil then exit; 
    (fill in the new message item) 
    IpMessages".Last".Event.Message := TheMsg; 
    IpMessages".Last".Event.ParamL := TheVkKey; 
    IpMessages".Last".Event.ParamH := 
MapVirtualKey(IpMessages".Last".Event.ParamL, 0) ; 
    AddVkMessage := true; 
    end; 
    function AddVkMsgPair(IpMessages : PMsgHeader; 
    ThelstMsg : Word; 
    The2ndMsg : Word; 
    TheVkKey : Word) : LongBool; 
    ($IFDEF Win32) stdcall; {$ELSE} export; ($ENDIF) 
    begin 
    AddVkMsgPair := false; 
    (add the first message) 
    if AddVkMessage(IpMessages, 
    ThelstMsg, 
    TheVkKey) = false then exit; 


     31.    Windows API  727 


    {add the second message) 
    if AddVkMessage(IpMessages, 
    The2ndMsg, 
    TheVkKey) = false then exit; 
    AddVkMsgPair := true; 
    end; 
    function AddKeyString(IpMessages : PMsgHeader; 
    IpBuffer : PChar) : LongBool; 
    f$IFDEF Win32} stdcall; {$ELSE} export; {$ENDIF} var 
    i : integer; 
    VkCode : word; 
    begin 
    AddKeyString := false; 
    i := 0; 
    (is the character buffer valid?} 
    if IpBuffer = nil then exit; 
    {loop through the character buffer) 
    while IpBuffer[i] <> #0 do begin 
    {get the characters vkKeyCode and shift state) 
    {$IFDEF Win32) 
    VkCode := VkKeyScan(lpBuffer[i]); 
    {$ELSE) 
    VkCode := VkKeyScan(ord(lpBuffer[i])) ; 
    {$ENDIF) 
    (does the character require a shift key down?) 
    if (HiByte(VkCode) and 1) = 1 then 
    if not AddVkMessage(IpMessages, 
    WM_KEYDOWN, 
    VK_SHIFT) then exit; 
    {make the character message) 
    if not AddVkMsgPair(IpMessages, 
    WM_KEYDOWN, 
    WM_KEYUP, 
    vkCode) then exit; 
    (does the character require a shift key up?) 
    if (HiByte(VkCode) and 1) = 1 then 
    if not AddVkMessage(IpMessages, 
    WM_KEYUP, 
    VK_SHIFT) then exit; 
    {point to the next character) 
    Inc(i) ; 
    end; 
    AddKeyString := true; 
    end; 
    function AddMouseMessage(IpMessages : PMsgHeader; 
    Msg : integer; 
    x : Smallint; 
     : Smallint) : LongBool; 
    ($IFDEF Win32) stdcall; ($ELSE) export; ($ENDIF) 
    begin 
    AddMouseMessage := false; 
    (is the buffer pointer valid?} 
    if IpMessages = nil then exit; 
    {create next message} 


    728                                        VI.   


    CreateNextMsgItem(IpMessages); 
    (was there an error?} 
    if IpMessages^.Last = nil then exit; 
    {fill in the message} 
    IpMessages".Last''.Event.Message := Msg; 
    IpMessages".Last^.Event.ParamL := x; 
    IpMessages"-Last^.Event.ParamH := y; 
    AddMouseMessage := true; 
    end; 
    exports 
    PlayBackProc index 1 name 'PLAYBACKPROC' resident 
    PlayMouseKeys index 2 name ' PLAYMOUSEKEYS"'' resident, 
    IsPlaying index 3 name 'ISPLAYING' resident, 
    CreateMsgBuff index 4 name 'CREATEMSGBUFF' resident, 
    DeleteMsgBuff index 5 name 'DELETEMSGBUFF' resident, 
    AddVkMessage index 6 name 'ADDVKMESSAGE' resident, 
    AddVkMsgPair index 7 name 'ADDVKMSGPAIR' resident, 
    AddKeyString index 8 name 'ADDKEYSTRING' resident, 
    AddMouseMessage index 9 name 'ADDMOUSEMESSAGE' resident; 
    begin 
    Playing := false; 
    end. 

              
 (  16         
 ).    TMsgItem  TMsgHeader    
Windows   . 
    Playing. , ,      . 
    IpMsg.     . 
     TheHook.    . 
             . 
     HC_SKIP.   .    , 
 . 
      GETNEXT.   . 
     HC_SYSMODALON.        
  ,       . 
     HC_SYSMODALOFF.     -  
.      ,   
    ,   . 
       ,      , 
          . 
     PlayMouseKeys ()   .   
           
,             
 .    ,  
 true. 
     IsPlaying ()    true,   
  ,      ,   
  ,         
  .        . 

    while IsPlaying do 
    Application.ProcessMessages; 

       (CreateMsgBuff  DeleteMsgBuff)    
 .   nil  ,     
 . 
     CreateNextMsgItem     .  
    DLL,     ,   . 
     AddVkMessage  AddVkMsgPair     
 .          
  . 
    AddKeyString    WM_KEYDOWN  WM_KEYUP   
  . 

     31.    Windows API                            729 

     , AddMouseMessage,     . 
          ,      
  Playing  false. 


      DLL PlayKeys 

         DLL   
 .  ,     DLL   
,        uses    
   .        31.2. 

     31.2, \UDELPHI3\CHP31\KEYIMP 

    unit keyimp; 
    interface 
    function PlayMouseKeys(IpMessages : pointer): LongBool; 
    {$IFDEF Win32) atdcall; {$ELSE} far; ($ENDIF) 
    function IsPlaying : LongBool; 
    t$IFDEF Win32} stdcall; ($ELSE) far; ($ENDIF) 
    procedure CreateMsgBuff(var IpMessages : pointer); 
    {$IFDEF Win32} stdcall; {$ELSE} far; ($ENDIF) 
    procedure DeleteMsgBuff(var IpMessages : pointer); 
    {$IFDEF Win32) stdcall; ($ELSE) far; ($ENDIF) 
    function AddVkMessage(IpMessages : pointer; 
    TheMsg : Word; 
    TheVkKey : Word) : LongBool; 
    ($IFDEF Win32) atdcall; ($ELSE) far; {$ENDIF} 
    function AddVkMsgPair(IpMessages : pointer; 
    ThelstMsg : Word; 
    The2ndMsg : Word; 
    TheVkKey : Word) : LongBool; 
    {$IFDEF Win32) stdcall; {$ELSE} far; <$ENDIF) 
    function AddKeyString(IpMessages : pointer; 
    IpBuffer : PChar) : LongBool; 
    {$IFDEF Win32) stdcall; ($ELSE) far; ($ENDIF) 
    function AddMouseMessage(IpMessages : pointer; 
    Msg : integer; 
    x : Smallint; 
     : Smallint) : LongBool; 
    {$IFDEF Win32) stdcall; {$ELSE} far; ($ENDIF) 
    implementation 
    function PlayMouseKeys; external 'PLAYKEYS' index 2; 
    function IsPlaying; external 'PLAYKEYS' index 3; 
    procedure CreateMsgBuff; external 'PLAYKEYS' index 4; 
    procedure DeleteMsgBuff; external 'PLAYKEYS' index 5; 
    function AddVkMessage; external 'PLAYKEYS' index 6; 


    730                                        VI.   


    function AddVkMsgPair; external 'PLAYKEYS' index 7; 
    function AddKeyString; external 'PLAYKEYS' index 8; 
    function AddMouseMessage; external'PLAYKEYS' index 9; 
    end. 

     ,        , 
     DLL    .                               

     PlayKeys 

      DLL  .   
 ___     (  
VCL-,   setfocus).       
,   Windows FindWindow,     
  BringWindowToTop   .    
 Application. ProcessMessage. ,      
   ,  CreateMsgBuff     
    .   , , 
   ""     IsPlaying,    
   PlayMouseKeys ().    ,  
    ,     while IsPlaying do 
Application. ProcessMessages;. ,   ,   
,  DeleteMsgBuff ().     : 

    procedure TFormI.ButtonlClick(Sender: TObject); 
    var 
    p: pointer; 
    begin 
    {  .} 
    Memol.SetFocus; 
    Application.ProcessMessages ; 
    (  .) 
    CreateMsgBuff(p) ; 
    (    .} 
    AddKeyString(p,'Now Is The Time!'); 
    (  ,      .} 
    while Is Playing do 
    Application.ProcessMessages; 
    ( .} 
    PlayMouseKey(p); 
    (  .) 
    while Is Playing do 
    Application.ProcessMessages; 
    ( .} 
    DeleteMsgBuff(p) ; 
    end; 

    ,    Memo     DLL  
   ,      ,      
           
  <Alt+Shift*Aa: . <PrintScreen>.     
  DelpHi,   Help   About   
. . <>    <Alt>.   
  ,'  '!   FindWindow 
()  BringWindowToTop ()     Delphi,   
 . 

    ( ,     <Alt>.) AddVkMsgPair(p, 
WMJ3YSKEYDOWN, WM_SYSKEYUP, VK_MENU) ; 


     31.    Windows API                            731 


    { ''    Help 
     ''      About. ) 
    AddKeyString(p,''); 
    {  <Alt>.} 
    AddVkMessagefp, WM_SYSKEYDOWN, VK_MENU); 
    ( 'team'.} 
    AddKeyString(p,'team' ) ; 
    {  <Alt>.) 
    AddVkMessagefp, WM_SYSKEYUP, VK_MENU); 

        .     
         . 

    procedure TFormI.ButtonlClick(Sender: TObject) ; 
    var 
    pt : TPoint; 
    p : pointer; 
    begin 
    ( .} 
    CreateMsgBuff(p) ; 
    (   .) 
    pt.x := Button2.Left + (Button2.Width div 2); 
    pt.y := Button2.Top + (Button2.Height div 2); 
    (  .) 
    pt := ClientToScreen(pt); 
    (  .} 
    AddMouseMessage(p,WM_MOUSEMOVE,pt.x,pt.); 
    AddMouseMessage(p,WM_LBUTTONDOWN,pt.x,pt.y); 
    AddMouseMessage(p,WM_LBUTTONUP,pt. x, pt. y) ; 
    (  ,   .) 
    while IsPlaying do 
    Application.PrssMessages; 
    (""  .} 
    PlayMouseKeys(p); 
    (  .} 
    while IsPlaying do 
    Application.ProcessMessages;. 
    ( .) 
    DeleteMsgBuff(p) ; 
    end; 

             ,  
      . 

     

          Windows API   
          
.    ,    Windows  ""! 

    732                                        VI.   
