AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

control applications with TV-tuner's remote control

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
dm



Joined: 04 May 2006
Posts: 8

PostPosted: Thu May 04, 2006 5:32 pm    Post subject: control applications with TV-tuner's remote control Reply with quote

First of all I'd like to thank the authors for the great scripting language. Smile
I've written a highly configurable script to control applications with RC of TV-tuner BeholdTV. If you don't happen to have BeholdTV tuner, this script still might be useful as an example of using RC API to control pc.
Here's the script. And here're some explanations.

Added 2008-05-30:
Another two scripts which complement RemoteControl script are now included (RemoteExplorer and PlaylistGenerator).


Last edited by dm on Sun Jun 29, 2008 3:56 pm; edited 5 times in total
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10480

PostPosted: Sat May 06, 2006 1:18 am    Post subject: Reply with quote

I checked out the explanations. Great presentation.

Thanks for posting your work.
Back to top
View user's profile Send private message Send e-mail
MusX



Joined: 08 Mar 2007
Posts: 1

PostPosted: Thu Mar 08, 2007 9:12 am    Post subject: Reply with quote

Hi, i have Leadtek Winfast 2000XP/EXPERT (link to product info at leadtek.com)
and the RC looks:

will this be hard (or available) to modify your script for my RC?
Back to top
View user's profile Send private message
dm



Joined: 04 May 2006
Posts: 8

PostPosted: Thu Mar 08, 2007 11:24 am    Post subject: Reply with quote

Leadtek must provide an API to query the state of the RC. If there is such API it won't be hard to make the script work with your RC.
Back to top
View user's profile Send private message
steliyan



Joined: 20 Apr 2007
Posts: 31

PostPosted: Fri Jan 11, 2008 2:00 pm    Post subject: Reply with quote

I want to port this to use it with averapi.dll, but no success. Here is an example written in delphi, but I can't test it, because I don't have delphi.

Any help will be appreciated.

Edit: I tested this: http://irlink.ru/download/Aver203,305,307,505_Test.rar and my remote is working with it. I'm trying to use the same DLL.

Edit2: This is cpp source of girder plugin:
Code:
//AVerTV Studio Girder plugin by Pavel Chromy

//based on plugin written by Michal Milczewski

 

#include <stdio.h>

#include <windows.h>

#include <winuser.h>

#include "girder.h"

#pragma argsused

 

#define AVERDEVICENUM 28

#define INT_POLE 100 //Remote Poling Interval (ms)

 

typedef void __cdecl (CALLBACK *THWInit)(void);

typedef int  __cdecl (CALLBACK *TGetRemoteData)(void);

//typedef void __cdecl (CALLBACK *TSetRemoteData)(int);

//typedef int  __cdecl (CALLBACK *TGetRemoteFlag)(void);

//typedef void __cdecl (CALLBACK *TSetRemoteFlag)(int);

//typedef int  __cdecl (CALLBACK *TIsRemoteDataReady)(void);

 

#pragma data_seg(".SHARDATA")

static HINSTANCE DllH = NULL;

static THWInit HWInit;

static TGetRemoteData GetRemoteData;

//static TSetRemoteData SetRemoteData;

//static TGetRemoteFlag GetRemoteFlag;

//static TSetRemoteFlag SetRemoteFlag;

//static TIsRemoteDataReady IsRemoteDataReady;

#pragma data_seg()

 

int PoleTimer=0;

bool IsDriverOK = false;

 

t_functions gir_sf;

 

VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);

 

/*=========================================================*/

 

bool LoadDll(HINSTANCE &DllH)

{

  CoInitialize(NULL);

 

  DllH=LoadLibrary("averapi.dll"); // try to load "averapi.dll" - win2k/me

 

 

  if (DllH==NULL) {

    MessageBox(GetForegroundWindow(),"The 'averapi.dll' library can't be found.\nYou have to install Medion software first.","Medion Girder plugin error",MB_OK | MB_ICONHAND| MB_SYSTEMMODAL);

    return false;

  }

  HWInit=(THWInit)GetProcAddress(DllH, "AVER_HWInit");

  GetRemoteData=(TGetRemoteData)GetProcAddress(DllH, "AVER_GetRemoteData");

  //SetRemoteData=(TSetRemoteData)GetProcAddress(DllH, "AVER_SetRemoteData");

  //GetRemoteFlag=(TGetRemoteFlag)GetProcAddress(DllH, "AVER_GetRemoteFlag");

  //SetRemoteFlag=(TSetRemoteFlag)GetProcAddress(DllH, "AVER_SetRemoteFlag");

  //IsRemoteDataReady=(TIsRemoteDataReady)GetProcAddress(DllH, "AVER_IsRemoteDataReady");

 

  if (!HWInit || !GetRemoteData) {

    MessageBox(GetForegroundWindow(),"Error during importing functions from Medion library.","Medion Girder plugin error",MB_OK | MB_ICONHAND| MB_SYSTEMMODAL);

    return false;

  }

 

  // hardware init

  HWInit(); //it takes a while with win9x drivers

    return true;

}

 

bool  UnloadDll(HINSTANCE &DllH)

{

  CoUninitialize();

  bool result = FreeLibrary(DllH);

  DllH = NULL;

   return result;

}

                         

   void StartTimer(int msec)

{

     if (PoleTimer) KillTimer(NULL,PoleTimer);

  PoleTimer=SetTimer(NULL,0,msec,(int(__stdcall *)())TimerProc);

  }

 

void StopTimer(void)

{

  if (PoleTimer) {

    KillTimer(NULL,PoleTimer);

    PoleTimer=0;

  }

}

 

void SendKey(int key)

{

    char payload='\0';

    char eventstr[16];

    sprintf(eventstr,"AVER_%02X",key);

    gir_sf.send_event(eventstr,&payload,1,AVERDEVICENUM);

}

 

VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)

{

  static int key;

 

  //AVerTV Studio - the IsRemoteDataReady() function does not behave as expected

  if ((key=GetRemoteData())&2) {

            SendKey(key);

  }

}

 

//grinder callings

/*=========================================================*/

 

extern "C" __declspec(dllexport) void CALLBACK gir_version(char *data, int size)

{

  strncpy(data,"2.0",size);

}

 

 

extern "C" __declspec(dllexport) void CALLBACK gir_name(char *data, int size)

{

  strncpy(data,"Medion remote controler",size);

}

 

 

extern "C" __declspec(dllexport) void CALLBACK gir_description(char *data, int size)

{

  strncpy(data,"Captures IR events from medion md2819",size);

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_devicenum()

{

  return AVERDEVICENUM;

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_requested_api(int max_api)

{

  return 1;

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_open

  (int gir_major_ver, int gir_minor_ver, int gir_micro_ver, p_functions p)

{

  if (p->size!=sizeof(s_functions))

    return GIR_FALSE;

 

  memcpy((void *)(&gir_sf), p, sizeof(s_functions));

 

         if (IsDriverOK=LoadDll(DllH))  return GIR_TRUE;

          return GIR_FALSE;

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_close()

{

  UnloadDll(DllH);

  return GIR_TRUE;

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_start()

{

  if (!IsDriverOK) return GIR_FALSE;

 

  StartTimer(INT_POLE);

  return GIR_TRUE;

}

 

 

extern "C" __declspec(dllexport) int CALLBACK gir_stop()

{

  if (!IsDriverOK) return GIR_FALSE;

 

  StopTimer();

  return GIR_TRUE;

}

 

/*=========================================================*/
Back to top
View user's profile Send private message
dm



Joined: 04 May 2006
Posts: 8

PostPosted: Sat Jan 12, 2008 2:06 pm    Post subject: Reply with quote

Hmm, given the girder source the port should be pretty straightforward. I would modify Core.ahk like this. Note the call to CoInitialize and CoUninitialize. Hope it helps.

P.S. Of course, you'll need to remap RC codes if it works, I haven't touched them.

Code:

/* ----------------------------------------------------------------------------
    Initialization, uninitialization, RC timer setup.
*/

; Initialize COM library
DllCall( "ole32\CoInitialize", "Uint", 0 )

; Load averapi.dll
HModule := DllCall( "LoadLibrary", "Str", "averapi.dll", "Cdecl" )
ResDllCall( "averapi.dll", "LoadLibrary" )
if ( HModule = 0 )
{
    MsgBox, 16, , averapi.dll could not be loaded
    ExitApp
}   

; Initialize card
DllCall( "averapi\AVER_HWInit", "Cdecl" )
ResDllCall( "averapi.dll", "AVER_HWInit" )

; Set window title match mode
SetTitleMatchMode, 2

; Form a window group of system windows
GroupAdd, WG_System, Program Manager ahk_class Progman
GroupAdd, WG_System, ahk_class WorkerW
GroupAdd, WG_System, ahk_class Shell_TrayWnd

; Set the subroutine to run on exit
OnExit, UninitAndExit

; Calculate number of signals to skip to ensure repeat delay/interval
NumSignalsRepeatDelay := Round( RCRepeatDelay/RCInterval ) - 1
NumSignalsRepeatInterval := Round( RCRepeatInterval/RCInterval ) - 1

; Initialize RC mode
RCMode = RCM_Wait
CntSignals = 0

; Initialize confirm mode
ConfirmMode = CM_None

; Set timer to check RC state
SetTimer, TimerRC, %RCInterval%

return

; --- The end of auto-execute section of the script ---

; Uninitialize the card on exit
UninitAndExit:

    ; Uninitialize COM library
    DllCall( "ole32\CoUninitialize" )
   
    ExitApp

/* ----------------------------------------------------------------------------
    Timer to check the state of the RC. RC key repeat delay and interval are
    controlled here.
*/
   
TimerRC:

    Res := DllCall( "averapi\GetRemoteData", "Cdecl Int" )
    ResDllCall( "averapi.dll", "GetRemoteData" )

    ; No button pressed
    if ( !Res&2 )
    {
        RCMode = RCM_Wait
        CntSignals = 0
        return
    }

    if ( ( ( RCMode = "RCM_RepeatDelay" ) && ( CntSignals < NumSignalsRepeatDelay ) )
            || ( ( RCMode = "RCM_RepeatInterval" ) && ( CntSignals < NumSignalsRepeatInterval ) ) )
    {
        CntSignals++
        return
    }

    if      ( Res = 0 )
    {
        RCKey = RCK_0
    }
    else if ( Res = 1 )
    {
        RCKey = RCK_1
    }
    else if ( Res = 2 )
    {
        RCKey = RCK_2
    }
    else if ( Res = 3 )
    {
        RCKey = RCK_3
    }
    else if ( Res = 4 )
    {
        RCKey = RCK_4
    }
    else if ( Res = 5 )
    {
        RCKey = RCK_5
    }
    else if ( Res = 6 )
    {
        RCKey = RCK_6
    }
    else if ( Res = 7 )
    {
        RCKey = RCK_7
    }
    else if ( Res = 8 )
    {
        RCKey = RCK_8
    }
    else if ( Res = 9 )
    {
        RCKey = RCK_9
    }
    else if ( Res = 10 )
    {
        RCKey = RCK_Recall
    }
    else if ( Res = 11 )
    {
        RCKey = RCK_Up
    }
    else if ( Res = 12 )
    {
        RCKey = RCK_Right
    }
    else if ( Res = 13 )
    {
        RCKey = RCK_Mode
    }
    else if ( Res = 14 )
    {
        RCKey = RCK_Sleep
    }
    else if ( Res = 15 )
    {
        RCKey = RCK_Audio
    }
    else if ( Res = 16 )
    {
        RCKey = RCK_Info
    }
    else if ( Res = 17 )
    {
        RCKey = RCK_TvAv
    }
    else if ( Res = 18 )
    {
        RCKey = RCK_Power
    }
    else if ( Res = 19 )
    {
        RCKey = RCK_Mute
    }
    else if ( Res = 20 )
    {
        RCKey = RCK_Menu
    }
    else if ( Res = 21 )
    {
        RCKey = RCK_Down
    }
    else if ( Res = 22 )
    {
        RCKey = RCK_Ok
    }
    else if ( Res = 23 )
    {
        RCKey = RCK_Teletext
    }
    else if ( Res = 24 )
    {
        RCKey = RCK_Left
    }
    else if ( Res = 26 )
    {
        RCKey = RCK_ChanUp
    }
    else if ( Res = 27 )
    {
        RCKey = RCK_VolUp
    }
    else if ( Res = 28 )
    {
        RCKey = RCK_Function
    }
    else if ( Res = 30 )
    {
        RCKey = RCK_ChanDown
    }
    else if ( Res = 31 )
    {
        RCKey = RCK_VolDown
    }
   
    if      RCMode = RCM_Wait
    {
        RCMode = RCM_RepeatDelay
    }
    else if RCMode = RCM_RepeatDelay
    {
        RCMode = RCM_RepeatInterval
    }
    CntSignals = 0
   
    if ( ( RCKey = RCKClose ) && ( RCMode = "RCM_RepeatInterval" ) )
        return
       
    Goto, AppManager
   
/* ----------------------------------------------------------------------------
    Application manager - manages remotely controlled applications.
    Firstly, the special RC keys for closing applications,
    shutdown, etc. are processed. Secondly, the special RC keys each
    controlling one application are processed. Thirdly, any other RC keys
    are passed to the handler of the active application.
*/

AppManager:

    ; Find managed application (RCKey = key controlling one of the applications)
    AppManaged := ""
    Loop
    {
        App := App%A_Index%
        if ( App = "" )
        {
            break
        }
        if ( RCKey = RCKApp%A_Index% )
        {
            AppManaged := App
            PathAppManaged := PathApp%A_Index%
            if ( PathAppManaged = "" )
            {
                MsgBox, 16, , Path not specified for %App%
                ExitApp
            }
            WinTitleAppManaged := WinTitleApp%A_Index%
            OwnerAppManaged := OwnerApp%A_Index%
        }
    }

    ; Find active application
    AppActive := ""
    Loop
    {
        App := App%A_Index%
        if ( App = "" )
        {
            break
        }
        if ( WinTitleApp%A_Index% = "" )
        {
            continue
        }
        IfWinActive, % WinTitleApp%A_Index%
        {
            AppActive := App
            HKCloseAppActive := HKCloseApp%A_Index%
            break
        }
    }
   
    ; RC key for closing applications is pressed
    if ( RCKey = RCKClose )
    {
        if ( AppActive != "" )
        {
            if ( HKCloseAppActive != "" )
            {
                Send, %HKCloseAppActive%
            }
            else
            {
                WinClose, A
            }
        }
        else IfWinNotActive, ahk_group WG_System
        {
            WinClose, A
        }
        else
        {
            ; No active windows, confirm that the user wants to shutdown the computer
            ConfirmMode = CM_Shutdown
            OSDText( TextShutdown, TextColorShutdown, FontNameShutdown, FontSizeShutdown, DelayShutdown )
        }
                   
        return
    }
   
    ; If confirmed shutdown the computer
    if ( ( ConfirmMode = "CM_Shutdown" ) && ( RCKey = RCKConfirm ) )
    {
        Shutdown, 8
        return
    }       

    ; RC key to show clock is pressed
    if ( RCKey = RCKClock )
    {
        Gosub, Wake
        TextClock = %A_Hour%:%A_Min%
        OSDText( TextClock, TextColorClock, FontNameClock, FontSizeClock, DelayClock )
        return
    }
   
    ; A special RC key managing one application is pressed, start/activate the
    ; application
    if ( AppManaged != "" )
    {
        if ( WinTitleAppManaged = "" )
        {
            Run, %PathAppManaged%, , UseErrorLevel
            ResRun( PathAppManaged )
            if ( OwnerAppManaged != "" )
            {
                Index := AppIndexByName( OwnerAppManaged )
                WinWait, % WinTitleApp%Index%
                WinActivate
            }
        }
        else IfWinNotExist, %WinTitleAppManaged%
        {
            Run, %PathAppManaged%, , UseErrorLevel
            ResRun( PathAppManaged )
        }
        else IfWinNotActive
        {
            WinActivate
        }
        return
    }
   
    ; Pass RC key to the handler of the active application
    if ( AppActive != "" )
    {
        LabelApp = %AppActive%
        if ( !IsLabel( LabelApp ) )
        {
            MsgBox, 16, , No handler for %AppActive% application (the handler must be called %LabelApp%)
            ExitApp
        }
        Goto, %LabelApp%
    }

    return

/* ----------------------------------------------------------------------------
    OSD text.
*/

; Show OSD text in the center of the screen
OSDText( Text, TextColor, FontName, FontSize, Delay )
{
    global TxtOSD
   
    Gui, Destroy
   
    Gui, +AlwaysOnTop +LastFound +Owner
    WinColor = White
    Gui, Color, %WinColor%
    WinSet, TransColor, %WinColor%
    Gui, -Caption

    X := 0.05*A_ScreenWidth
    W := 0.90*A_ScreenWidth
    Gui, Font, s%FontSize%, %FontName%
    Gui, Add, Text, x%X% w%W% Center c%TextColor% vTxtOSD, %Text%

    Gui, Show, NoActivate

    SetTimer, RemoveOSD, %Delay%

    return
}

; Remove OSD
RemoveOSD:

    SetTimer, RemoveOSD, Off
    Gui, Destroy

    ; Set confirm mode to none in case OSD was used to confirm something
    ConfirmMode = CM_None
   
    return
       
/* ----------------------------------------------------------------------------
    Auxilary routines.
*/

; Test the result of DllCall
ResDllCall( DllName, FuncName )
{
    if ( ErrorLevel = 0 )
        return
    if ( ErrorLevel = -1 )
    {
        MsgBox, 16, , DLL name or function name specified incorrectly when calling function %FuncName% in DLL %DllName%
        ExitApp
    }
    if ( ErrorLevel = -2 )
    {
        MsgBox, 16, , Return type or argument type specified incorrectly when calling function %FuncName% in DLL %DllName%
        ExitApp
    }
    if ( ErrorLevel = -3 )
    {
        MsgBox, 16, , %DllName% could not be accessed
        ExitApp
    }
    if ( ErrorLevel = -4 )
    {
        MsgBox, 16, , Function %FuncName% not found inside %DllName%
        ExitApp
    }
    StringLeft, c, ErrorLevel, 1
    StringTrimLeft, n, ErrorLevel, 1
    if ( c = "A" )
    {
        MsgBox, 16, , Size of argument list incorrect by %n% bytes (or cdecl required) when calling function %FuncName% in DLL %DllName%
        ExitApp
    }
    if ( ErrorLevel > 0 )
    {
        MsgBox, 16, , Fatal exception %ErrorLevel% when calling function %FuncName% in DLL %DllName%
        ExitApp
    }
    return
}

; Test the result of Run/RunWait
ResRun( Path )
{
    if ErrorLevel = ERROR
    {
        MsgBox, 16, , Failed to launch %Path%
        ExitApp
    }
}

; Get application index by its name
AppIndexByName( App )
{
    Loop
    {
        if ( App%A_Index% = "" )
        {
            break
        }
        if ( App = App%A_Index% )
        {
            return A_Index
        }
    }
    return RES_NotFound
}

; Wake the computer
Wake:
    Send, ^#!{F12}
    return
Back to top
View user's profile Send private message
steliyan



Joined: 20 Apr 2007
Posts: 31

PostPosted: Mon Jan 14, 2008 6:20 am    Post subject: Reply with quote

Throws me an exception:
Back to top
View user's profile Send private message
steliyan



Joined: 20 Apr 2007
Posts: 31

PostPosted: Mon Jan 14, 2008 1:46 pm    Post subject: Reply with quote

This is fully working code in Delphi (tested - thanks to AlexPas):
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Controls, Forms,
  Dialogs, ActiveX, Registry, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Memo1: TMemo;
    Panel1: TPanel;
    Label1: TLabel;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    AVerAPI: HInst;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TAVerHWInit = function (Handle: HWND): Byte; cdecl; // AVER_HWInit
  TAVerGetRemoteData = function (var Button: Byte): Integer; cdecl; // AVER_GetRemoteData
  TAVerFree = procedure (Data: Integer); cdecl; // AVER_Free

var
  AVerHWInit: TAVerHWInit;
  AVerGetRemoteData: TAVerGetRemoteData;
  AVerFree: TAVerFree;
  AverAppRun: Bool = False;
  AVerAppFile: String;
  LastButton: Integer = 0;

procedure TForm1.FormCreate(Sender: TObject);
var
  Result: Integer;
  hAVerApp: HWnd;
  Reg: TRegistry;
  FileName: String;
begin
  hAVerApp := FindWindow('AVerRemoteApp', nil);
  if hAVerApp <> 0 then
    begin
      Memo1.Lines.Add('Closing AVer QuickTV application');
      AverAppRun := True;
      PostMessage(hAVerApp, WM_COMMAND, $9C49, 0);
    end
  else
    Memo1.Lines.Add('AVer QuickTV application is not started');

  CoInitialize(nil);
  AVerAPI := 0;
  Reg := TRegistry.Create(KEY_READ);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    try
      Reg.OpenKeyReadOnly('\SOFTWARE\AVerMedia TECHNOLOGIES, Inc.');
      try
        FileName := Reg.ReadString('Application Path');
        if FileName = '' then
          raise Exception.Create('Value "Application Path" not found');
      except
        on E: Exception do
          begin
            Memo1.Lines.Add(Format('Registry reading: Error "%s"', [E.Message]));
            Exit;
          end;
      end
    except
      Memo1.Lines.Add('Registry key "HKEY_LOCAL_MACHINE\SOFTWARE\AVerMedia TECHNOLOGIES, Inc." not found');
    end;
  finally
    FreeAndNil(Reg);
  end;
  Memo1.Lines.Add(Format('Registry reading: OK averapi.dll path is "%s"', [FileName]));
  AVerAppFile := IncludeTrailingPathDelimiter(FileName) + 'QuickTV.exe';
  FileName := IncludeTrailingPathDelimiter(FileName) + 'averapi.dll';
  AVerAPI := LoadLibrary(PChar(FileName));
  if AVerAPI <> 0 then
    begin
      Memo1.Lines.Add('Loading averapi.dll: OK');
      AVerHWInit :=
        TAVerHWInit(GetProcAddress(AVerAPI, 'AVER_HWInit'));
      if @AVerHWInit <> nil then
        Memo1.Lines.Add('Get function AVER_HWInit: OK')
      else
        Memo1.Lines.Add(Format('Get function AVER_HWInit: Error %d', [GetLastError]));
      AVerGetRemoteData :=
        TAVerGetRemoteData(GetProcAddress(AVerAPI, 'AVER_GetRemoteData'));
      if @AVerGetRemoteData <> nil then
        Memo1.Lines.Add('Get function AVER_GetRemoteData: OK')
      else
        Memo1.Lines.Add(Format('Get function AVER_GetRemoteData: Error %d', [GetLastError]));
      AVerFree :=
        TAVerFree(GetProcAddress(AVerAPI, 'AVER_Free'));
      if @AVerFree <> nil then
        Memo1.Lines.Add('Get function AVER_Free: OK')
      else
        Memo1.Lines.Add(Format('Get function AVER_Free: Error %d', [GetLastError]));
      Result := AVerHWInit(0);
      if Result = 0 then
        Memo1.Lines.Add('Call function AVER_HWInit: OK')
      else
        Memo1.Lines.Add(Format('Call function AVER_HWInit: Error %d', [Result]));
    end
  else
    Memo1.Lines.Add(Format('Loading averapi.dll: Error %d', [GetLastError]));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if AVerAPI <> 0 then
    AVerFree(0);
  CoUninitialize;
  if AverAppRun then
    WinExec(PChar(AVerAppFile), 0);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Data: Byte;
  Result: Integer;
begin
  Result := -1;
  if AVerAPI <> 0 then
    try
      Data := $FF;
      if AVerGetRemoteData(Data) = 0 then
        begin
          if (Data and 2) <> 0 then
            begin
              //LastButton := Data and $FD;
              Result := Data and $FF;
            end
          else
            Result := LastButton;
        end
    except
    end;
  Label1.Caption := IntToStr(Result);
end;

end.



Here is what I've done (in AHK):
Code:
#SingleInstance Force

Gui, Add, Text, x5 y5  vText1, Button:
Gui, Add, Text, x45 y5 vText2, -1
Gui, Add, Edit, x5 y20 w300 h100 vEdit1 ReadOnly
Gui, Show,, AverAPI

DllCall("ole32\CoInitialize", "Uint", 0)

API := DllCall("LoadLibrary", "Str", "averapi.dll", "Cdecl")

If API <> 0
{
   GuiControl,, Edit1, Loading averapi.dll - OK!

   HWInit := DllCall("GetProcAddress", UInt, API, "str", "AVER_HWInit")
   GuiControlGet, Temp,, Edit1
   If Temp <> 0
      GuiControl,, Edit1, %Temp%`nGet function AVER_HWInit - OK!
   Else
      GuiControl,, Edit1, %Temp%`nGet function AVER_HWInit - FAILED!

   GetRemoteData := DllCall("GetProcAddress", UInt, API, "str", "AVER_GetRemoteData")
   GuiControlGet, Temp,, Edit1
   If Temp <> 0
      GuiControl,, Edit1, %Temp%`nGet function AVER_GetRemoteData - OK!
   Else
      GuiControl,, Edit1, %Temp%`nGet function AVER_GetRemoteData - FAILED!

   Free := DllCall("GetProcAddress", UInt, API, "str", "AVER_Free")
   GuiControlGet, Temp,, Edit1
   If Temp <> 0
      GuiControl,, Edit1, %Temp%`nGet function AVER_Free - OK!
   Else
      GuiControl,, Edit1, %Temp%`nGet function AVER_Free - FAILED!
}
Else
   GuiControl,, Edit1, Loading averapi.dll - FAILED!

SetTimer, TimerRC, 250
   
Return

TimerRC:
   Res := DllCall("averapi\AVER_GetRemoteData", UChar, ff, "Cdecl")
   GuiControl,, Text2, %Res%
return

ButtonExit:
   If API <> 0
      DllCall( "averapi\AVER_Free", "Cdecl" )
   DllCall( "ole32\CoUninitialize", "Uint", 0 )
   GuiClose:
ExitApp
Back to top
View user's profile Send private message
dm



Joined: 04 May 2006
Posts: 8

PostPosted: Mon Jan 14, 2008 6:03 pm    Post subject: Reply with quote

steliyan wrote:
Throws me an exception:
I guess, this line is wrong then (yeah I have also misspelled the function name):
Res := DllCall( "averapi\GetRemoteData", "Cdecl Int" )
The function must have an argument.

I think the problem in your code is with the same line:
Res := DllCall("averapi\AVER_GetRemoteData", UChar, ff, "Cdecl")
Here the RC code is returned in the function argument. In order for this to work the argument must have UChar* type, not UChar. Try the following instead:
Res := DllCall("averapi\AVER_GetRemoteData", "UChar*", Data, "Cdecl")
Data should contain the code.
Back to top
View user's profile Send private message
steliyan



Joined: 20 Apr 2007
Posts: 31

PostPosted: Mon Jan 14, 2008 7:18 pm    Post subject: Reply with quote

Blahh, that pointers. Thanks, now it's working like charm.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group