AutoHotkey Community

It is currently May 27th, 2012, 12:07 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: [SOLVED] GoTView RC
PostPosted: February 25th, 2011, 10:00 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
[Moderator's note: Moved topic from Bug Reports to Ask for Help.]

Windows 7 Ultimate (64-bit)
AutoHotkey_L v1.0.92.02 Unicode (32-bit)

I am trying to call functions from the gtvremote.dll (GoTView Remote Control SDK).

Code:
Exported Functions List
Created by using DLL Export Viewer http://www.nirsoft.net/utils/dll_export_viewer.html
┌───────────────────────────────────────────────────────────────────────────────────────┬────────────┬────────────┬─────────┬───────────────┐
│ Function Name                                                                         │ Address    │ Relative   │ Ordinal │ Filename      │
├───────────────────────────────────────────────────────────────────────────────────────┼────────────┼────────────┼─────────┼───────────────┤
│ public: __thiscall CGTVRemote::CGTVRemote(void)                                       │ 0x10001145 │ 0x00001145 │ 1 (0x1) │ gtvremote.dll │
│ public: __thiscall CGTVRemote::~CGTVRemote(void)                                      │ 0x100011a2 │ 0x000011a2 │ 2 (0x2) │ gtvremote.dll │
│ public: class CGTVRemote & __thiscall CGTVRemote::operator=(class CGTVRemote const &) │ 0x10001000 │ 0x00001000 │ 3 (0x3) │ gtvremote.dll │
│ public: long __thiscall CGTVRemote::GetCode(unsigned char *)                          │ 0x100011c3 │ 0x000011c3 │ 4 (0x4) │ gtvremote.dll │
│ public: char * __thiscall CGTVRemote::GetDeviceName(unsigned long)                    │ 0x100011e2 │ 0x000011e2 │ 5 (0x5) │ gtvremote.dll │
│ public: long __thiscall CGTVRemote::SelectDevice(unsigned long)                       │ 0x10001200 │ 0x00001200 │ 6 (0x6) │ gtvremote.dll │
└───────────────────────────────────────────────────────────────────────────────────────┴────────────┴────────────┴─────────┴───────────────┘

Here is my script (partially working).
Calling to SelectDevice is commented out because AutoHotkey_L crashes on it.
Other functions seems to work fine.
Code:
#NoEnv
#SingleInstance Force
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
OnExit, ExitSub

Gui, Font, , Consolas
Gui, Add, Text, vStatic1, Capture Devices (0):
Gui, Add, ListView, vListView1, Index|Device
Gui, Add, Text, vStatic2, Remote Codes:
Gui, Add, ListView, vListView2, Elapsed|Code
Gui, Add, StatusBar
Gui, Show, , GoTView RC
Menu, Tray, Tip, GoTView RC

IfNotExist, gtvremote.dll, UrlDownloadToFile, http://www.autohotkey.net/~Big_Digger/GoTView/gtvremote.dll, gtvremote.dll

if !hModule := DllCall("GetModuleHandle", "Str", "gtvremote", "Ptr")
    hModule := DllCall("LoadLibrary", "Str", "gtvremote", "Ptr")

pCGTVRemote := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 1, "Ptr")
pGetDeviceName := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 5, "Ptr")
pSelectDevice := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 6, "Ptr")
pGetCode := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 4, "Ptr")

pRemote := DllCall(pCGTVRemote, "Ptr")
Loop
{
    if !DeviceName := DllCall(pGetDeviceName, "UInt", A_Index - 1, "AStr")
        Break
    GuiControl, , Static1, Capture Devices (%A_Index%):
    Gui, ListView, ListView1
    LV_Add("", A_Index - 1, DeviceName)
    if InStr(DeviceName, "GOTVIEW")
    {
        ; Result := DllCall(pSelectDevice, "UInt", A_Index - 1, "Int")
        if (Result = 0)
        {
            LV_Modify(A_Index, "Select")
            SetTimer, TimerSub, 50
        }
    }
}
Return


TimerSub:
Result := DllCall(pGetCode, "UChar*", RemoteCode, "Int")
if (Result = 0 and RemoteCode < 255)
{
    Elapsed := A_TickCount - PrevCount, PrevCount := A_TickCount
    Gui, ListView, ListView2
    RowNumber := LV_Add("", Elapsed, RemoteCode)
    LV_Modify(RowNumber, "Vis")
}
Return

ExitSub:
GuiClose:
if hModule := DllCall("GetModuleHandle", "Str", "gtvremote", "Ptr")
    DllCall("FreeLibrary", "Ptr", hModule)
ExitApp

Image
gtvremote.h
Code:
#ifdef GTVREMOTE_EXPORTS
#define GTVREMOTE_API __declspec(dllexport)
#else
#define GTVREMOTE_API __declspec(dllimport)
#endif

// This class is exported from the gtvremote.dll


// Supported TV tuners:
// 1 - GoTView PCI (Conexant driver)
// 2 - GoTView PCI (Gotview driver)
// 3 - GoTView PCI 7134
// 4 - GoTView PCI 7135
// 5 - GoTView PCI DVD  (IVAC15 driver)
// 6 - GoTView PCI DVD  (Falcon2 driver)
// 7 - GoTView PCI DVD3
// 8 - GoTView PCI HYBRID

typedef enum CARD_TYPE
{
   CARD_UNKNOWN=0,
   CARD_878_CX=1,
   CARD_878_GT=2,
   CARD_7134=3,
   CARD_7135=4,

//Cards with a similar remote control
   CARD_DVD_IVAC=5,   
   CARD_DVD_FALCON=6,
   CARD_DVD_RAPTOR=7,
   CARD_CXVASVID=8,

//  GoTView PCI 713X with BDA driver
   CARD_713X_BDA=9
//

}CARD_TYPE;

class GTVREMOTE_API CGTVRemote
{

public:
   CGTVRemote(void);
   ~CGTVRemote(void);

   // dwCode receives a code of the pressed button, if any; otherwise, the value is 0xFF.
   // If the function succeeds, the return value is 0 (S_OK). Otherwise, it returns an HRESULT error code.
   HRESULT GetCode(BYTE* dwCode);
   // Returns a name of the capture device. Otherwise, returns NULL (if devnum+1 greater than number of devices in the system);
   LPSTR   GetDeviceName(DWORD devnum);
   // Selects a capture device. If the function succeeds, the return value is 0 (S_OK). Otherwise, it returns an HRESULT error code.
   HRESULT SelectDevice(DWORD devnum);
   // Cards based on the bt878 chip (GoTView PCI) been 2 modifications of the RC controllers. If the left and right buttons do not works, m_bChipTypeTM must be set to true;
   // Does not affects other cards.
   BOOL    m_bChipTypeTM;
   CARD_TYPE m_cCardType;
};

gtvremotetest.cpp
Code:
// gtvremotetest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "gtvremotetest.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "gtvremote.h"

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
   int nRetCode = 0;

   // initialize MFC and print and error on failure
   if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
   {
      // TODO: change error code to suit your needs
      cerr << _T("Fatal Error: MFC initialization failed") << endl;
      nRetCode = 1;
   }


CGTVRemote* Remote=new CGTVRemote;

LPSTR pszDevname=NULL;
DWORD num=0;

do
{
   pszDevname=Remote->GetDeviceName(num);
   if(pszDevname)
   {
      printf("%s\n",pszDevname);
      char *ptr;
      for (ptr = pszDevname; *ptr; ptr++)*ptr = toupper( *ptr );
      if(strstr(pszDevname,"GOTVIEW"))break;
   }
   num++;
}while(pszDevname);


Remote->SelectDevice(num);

Remote->m_bChipTypeTM=false;

switch (Remote->m_cCardType)
{
   case CARD_878_CX:      {printf("CardType CARD_878_CX\n");   break;}
   case CARD_878_GT:      {printf("CardType CARD_878_GT\n");   break;}
   case CARD_7134:         {printf("CardType CARD_7134\n");   break;}
   case CARD_7135:         {printf("CardType CARD_7135\n");   break;}
   case CARD_DVD_IVAC:      {printf("CardType CARD_DVD_IVAC\n");break;}
   case CARD_DVD_FALCON:   {printf("CardType CARD_DVD_FALCON\n");break;}
   case CARD_DVD_RAPTOR:   {printf("CardType CARD_DVD_RAPTOR\n");break;}
   case CARD_CXVASVID:      {printf("CardType CARD_CXVASVID\n");break;}
   case CARD_713X_BDA:      {printf("CardType CARD_713X_BDA\n");break;}
   case CARD_UNKNOWN:
   default :            {printf("CardType CARD_UNKNOWN\n");break;}
}

while(true)
{
   BYTE bCode=0xFF;
   Remote->GetCode(&bCode);
   if(bCode!=0xFF)printf("Code=%d\n",bCode);
   Sleep(50);
}


return nRetCode;
}


Last edited by Big Digger on March 2nd, 2011, 9:09 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 25th, 2011, 10:11 am 
Online
User avatar

Joined: May 5th, 2007, 7:24 pm
Posts: 1240
Location: Seville, Spain
AutoHotkey(_L) doesn't support thiscall.

_________________
fincs
Highly recommended: AutoHotkey_L (see why) (all my code snippets require it)
Formal request to polyethene - I support the unity of the AutoHotkey community
Get SciTE4AutoHotkey v3.0.00 (Release Candidate)
[My project list]


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 25th, 2011, 10:52 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
fincs
But why the GetDeviceName and GetCode are working in this case?..
What else can I do? remote_sdk.zip contains the following files:
Code:
gtvremote.h             1,5 k       2007-08-20 11:19    -a--
gtvremote.lib           3,0 k       2007-08-20 13:18    -a--
gtvremote64.lib         3,1 k       2007-08-20 13:20    -a--
gtvremotetest.clw       250 b       2005-09-15 05:21    -a--
gtvremotetest.cpp       1,9 k       2007-11-26 14:54    -a--
gtvremotetest.dsp       5,7 k       2007-11-26 14:54    -a--
gtvremotetest.dsw       549 b       2005-09-15 05:21    -a--
gtvremotetest.h         347 b       2005-09-15 05:21    -a--
gtvremotetest.rc        1,4 k       2005-09-15 05:21    -a--
keycodes.txt            1,0 k       2007-11-26 15:02    -a--
Resource.h              454 b       2005-09-15 05:21    -a--
StdAfx.cpp              300 b       2005-09-15 05:21    -a--
StdAfx.h                1,0 k       2005-09-15 05:21    -a--
24 k in 14 files

[Release]
gtvremote.dll         120,0 k       2007-08-20 13:18    -a--
gtvremotetest.exe       6,0 k       2007-11-26 14:54    -a--
126 k in 2 files

[Release64]
gtvremote64.dll        27,0 k       2007-08-20 13:20    -a--
gtvremotetest64.exe     7,0 k       2007-08-20 12:51    -a--
34 k in 2 files


Last edited by Big Digger on February 26th, 2011, 8:08 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 25th, 2011, 5:30 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Quote:
But why the GetDeviceName and GetCode are working in this case?..
__thiscall is almost identical to __stdcall except for the this pointer (in the register). So, as long as a function doesn't have to access the object and/or its members, AHK's dllcall may work. GetCode and GetDeviceName look like mere enum/get functions, i.e., no need to access this pointer. However, SelectDevice looks like to be gonna set the members m_bChipTypeTM and/or m_cCardType, so tried to access (wrong) this and crashed.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 26th, 2011, 11:42 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Sean
Thanks for your reply.
I have no problem with the gtvremote64.dll.
The script below is working flawless on my 64-bit system.
But I would like to write a code that can be used on both 32-bit and 64-bit platforms.
Maybe it is possible to compile a usable DLL from the existing gtvremote.h (with some modifications) and gtvremote.lib?
I have found two articles, which probably can be useful for me, but I know nothing about C++ :(
http://www.codeproject.com/KB/mcpp/usingcppdll.aspx
http://www.codeproject.com/KB/cs/marshalCPPclass.aspx
I have Visual Studio 2010, but I don't really know how to approach him :?
Code:
#NoEnv
#SingleInstance Force
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
OnExit, ExitSub

Gui, Font, , Consolas
Gui, Add, Text, vStatic1, Capture Devices (0):
Gui, Add, ListView, vListView1, Index|Device
Gui, Add, Text, vStatic2, Remote Codes:
Gui, Add, ListView, vListView2, Elapsed|Code
Gui, Add, StatusBar
Gui, Show, , GoTView RC x64
Menu, Tray, Tip, GoTView RC x64

IfNotExist, gtvremote64.dll, UrlDownloadToFile, http://www.autohotkey.net/~Big_Digger/GoTView/gtvremote64.dll, gtvremote64.dll

if !hModule := DllCall("GetModuleHandle", "Str", "gtvremote64", "Ptr")
    hModule := DllCall("LoadLibrary", "Str", "gtvremote64", "Ptr")

pCGTVRemote := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 1, "Ptr")
pGetDeviceName := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 5, "Ptr")
pSelectDevice := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 6, "Ptr")
pGetCode := DllCall("GetProcAddress", "Ptr", hModule, "UInt", 4, "Ptr")

pRemote := DllCall(pCGTVRemote, "Ptr")
Loop
{
    if !DeviceName := DllCall(pGetDeviceName, "Ptr", pRemote, "UInt", A_Index - 1, "AStr")
        Break
    GuiControl, , Static1, Capture Devices (%A_Index%):
    Gui, ListView, ListView1
    LV_Add("", A_Index - 1, DeviceName)
    if InStr(DeviceName, "GOTVIEW")
    {
        Result := DllCall(pSelectDevice, "Ptr", pRemote, "UInt", A_Index - 1, "Int")
        if (Result = 0)
        {
            LV_Modify(A_Index, "Select")
            SetTimer, TimerSub, 50
        }
    }
}
Return


TimerSub:
Result := DllCall(pGetCode, "Ptr", pRemote, "UChar*", RemoteCode, "Int")
if (Result = 0 and RemoteCode < 255)
{
    Elapsed := A_TickCount - PrevCount, PrevCount := A_TickCount
    Gui, ListView, ListView2
    RowNumber := LV_Add("", Elapsed, RemoteCode)
    LV_Modify(RowNumber, "Vis")
}
Return

ExitSub:
GuiClose:
if hModule := DllCall("GetModuleHandle", "Str", "gtvremote64", "Ptr")
    DllCall("FreeLibrary", "Ptr", hModule)
ExitApp

Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 26th, 2011, 5:17 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Big Digger wrote:
I have no problem with the gtvremote64.dll.
Actually that was my immediate suggestion, using 64bit dll instead as there is only one calling convention with x64. But, I removed that shortly after I noticed that the constructor was also of __thiscall (with 32bit dll), which I was not sure of was normal.

Quote:
Maybe it is possible to compile a usable DLL from the existing gtvremote.h (with some modifications) and gtvremote.lib?
I think so.

PS. I suppose your usage of pCGTVRemote is unsafe. I realized after a thought that not only constructor is of __thiscall is natural but also it actually needs this pointer, which is just a (newly) allocated memory in the case. So, I think you should allocate a new mem (via malloc, I suppose) and supply it as the first parameter (with 64bit dll).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 27th, 2011, 10:02 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Sean wrote:
I suppose your usage of pCGTVRemote is unsafe. I realized after a thought that not only constructor is of __thiscall is natural but also it actually needs this pointer, which is just a (newly) allocated memory in the case. So, I think you should allocate a new mem (via malloc, I suppose) and supply it as the first parameter (with 64bit dll).

Sorry, I do not understand all the subtleties..
What do you mean? Something similar to:
Code:
VarSetCapacity(Remote, 40)
pRemote := DllCall(pCGTVRemote, "Ptr", &Remote, "Ptr")

I have checked the Remote variable after calling DllCall, it contains only zeros.

Sean wrote:
Quote:
Maybe it is possible to compile a usable DLL from the existing gtvremote.h (with some modifications) and gtvremote.lib?
I think so.

Can I ask for your help, please?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 27th, 2011, 1:59 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Big Digger wrote:
I have checked the Remote variable after calling DllCall, it contains only zeros.
I think that's a good sign. BTW, what I meant was more like:
Code:
VarSetCapacity(Remote, 40)   ; 8 bytes appear to be enough.
pRemote := &Remote
DllCall(pCGTVRemote, "Ptr", pRemote)

Quote:
Can I ask for your help, please?
Why don't you export new functions which are wrappers around those member functions?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 28th, 2011, 9:21 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
Sean wrote:
BTW, what I meant was more like:
Code:
VarSetCapacity(Remote, 40)   ; 8 bytes appear to be enough.
pRemote := &Remote
DllCall(pCGTVRemote, "Ptr", pRemote)

What do you think about this way (it's working):
Code:
DllCall(pCGTVRemote, "Ptr*", Remote)
DllCall(pSelectDevice, "Ptr", &Remote, "UInt", 1, "Int")

After calling to the pGetDeviceName and/or pSelectDevice, Remote contains 6 bytes in hex 30 00 00 00 08 00.

Sean wrote:
Why don't you export new functions which are wrappers around those member functions?

I don't know how to do it, as I am not VC++ programmer..


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 2nd, 2011, 9:09 am 
Offline

Joined: February 7th, 2009, 5:37 am
Posts: 43
I have found the ready-made wrapper.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: BrandonHotkey and 17 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group