#include "stdafx.h" #ifdef __linux__ #include #include #include #include #include #endif #include #include #include "AddInNative.h" #include #define TIME_LEN 34 #define BASE_ERRNO 7 static wchar_t *g_PropNames[] = {L"IsInited", L"Version", L"MaxTimeBetweenClicks", L"BufferSize", L"Prefix", L"Suffix"}; static wchar_t *g_MethodNames[] = {L"Init", L"Deinit", L"GetBarcode"}; static wchar_t *g_PropNamesRu[] = {L"Инициализирован", L"Версия", L"МаксВремяМеждуНажатиями", L"РазмерБуфера", L"Префикс", L"Суффикс"}; static wchar_t *g_MethodNamesRu[] = {L"Инициализация", L"Деинициализация", L"ПолучитьШтрихкод"}; static const wchar_t g_kClassNames[] = L"Scaner"; static IAddInDefBase *pAsyncEvent = NULL; uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, uint32_t len = 0); uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len = 0); uint32_t getLenShortWcharStr(const WCHAR_T* Source); /* HHOOK hHook; HWND hWnd; unsigned long barcode_time = 0; wchar_t barcode_string[250]; int barcode_current = 0; */ /* LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam) { MSG *msg = (MSG *)lParam; if (code == HC_ACTION && wParam == PM_REMOVE) { if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) { if ((msg->time - barcode_time) < 30 || !barcode_time) { barcode_string[barcode_current] = msg->wParam; barcode_time = msg->time; if (msg->wParam == 0x000D) { barcode_string[barcode_current] = 0x0000; barcode_current = 0; barcode_time = 0; pAsyncEvent->ExternalEvent(L"Scaner", L"KeyBd", barcode_string); } else barcode_current++; } else { barcode_current = 0; barcode_time = 0; } msg->message = 0x00; } } return CallNextHookEx(pAsyncEvent-> hHook, code, wParam, lParam); } */ /* ThreadProc && GetMsgProc */ #include "bcbuffer.h" CircularBuffer bcbuf; CAddInNative *driver; DWORD WINAPI ThreadProc(CONST LPVOID lpParam) { driver->m_boolThreadExit = false; while (!driver->m_boolThreadExit) { pAsyncEvent->ExternalEvent(L"Scaner", L"Thread", L""); Sleep(5000); } driver->m_boolThreadExit = false; return 0; } LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam) { MSG *msg = (MSG *)lParam; if (code == HC_ACTION && wParam == PM_REMOVE) { if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) { wchar_t buf[64]; wsprintf(buf, L"%x - %x", msg->wParam, msg->time); pAsyncEvent->ExternalEvent(L"Scaner", L"KeyBd", buf); msg->message = 0; } } return CallNextHookEx((HHOOK)driver->m_hhookKeyBDHook, code, wParam, lParam); } //---------------------------------------------------------------------------// long GetClassObject(const WCHAR_T* wsName, IComponentBase** pInterface) { if(!*pInterface) { *pInterface = new CAddInNative; driver = (CAddInNative *)*pInterface; return (long)*pInterface; } return 0; } //---------------------------------------------------------------------------// long DestroyObject(IComponentBase** pIntf) { if(!*pIntf) return -1; delete *pIntf; *pIntf = 0; return 0; } //---------------------------------------------------------------------------// const WCHAR_T* GetClassNames() { static WCHAR_T* names = 0; if (!names) ::convToShortWchar(&names, g_kClassNames); return names; } // CAddInNative //---------------------------------------------------------------------------// CAddInNative::CAddInNative() { m_iMemory = 0; m_iConnect = 0; m_boolInited = false; m_longMaxTimeBetweenClicks = 30; m_longBufferSize = 5000; wcscpy(m_wstrVersion, L"1.0"); wcscpy(m_wstrPrefix, L""); wcscpy(m_wstrSuffix, L""); m_longTypeBarcode = 0; wcscpy(m_wstrBarcode, L"123"); } //---------------------------------------------------------------------------// CAddInNative::~CAddInNative() { } //---------------------------------------------------------------------------// bool CAddInNative::Init(void* pConnection) { m_iConnect = (IAddInDefBase*)pConnection; pAsyncEvent = m_iConnect; return m_iConnect != NULL; } //---------------------------------------------------------------------------// long CAddInNative::GetInfo() { // Component should put supported component technology version // This component supports 2.0 version return 2000; } //---------------------------------------------------------------------------// void CAddInNative::Done() { } ///////////////////////////////////////////////////////////////////////////// // ILanguageExtenderBase //---------------------------------------------------------------------------// bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) { wchar_t *wsExtension = L"AddInNativeExtension"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* dest = 0; if (m_iMemory) { if(m_iMemory->AllocMemory((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, wsExtension, iActualSize); return true; } return false; } //---------------------------------------------------------------------------// long CAddInNative::GetNProps() { // You may delete next lines and add your own implementation code here return ePropLast; } //---------------------------------------------------------------------------// long CAddInNative::FindProp(const WCHAR_T* wsPropName) { long plPropNum = -1; wchar_t* propName = 0; ::convFromShortWchar(&propName, wsPropName); plPropNum = findName(g_PropNames, propName, ePropLast); if (plPropNum == -1) plPropNum = findName(g_PropNamesRu, propName, ePropLast); delete[] propName; return plPropNum; } //---------------------------------------------------------------------------// const WCHAR_T* CAddInNative::GetPropName(long lPropNum, long lPropAlias) { if (lPropNum >= ePropLast) return NULL; wchar_t *wsCurrentName = NULL; WCHAR_T *wsPropName = NULL; int iActualSize = 0; switch(lPropAlias) { case 0: // First language wsCurrentName = g_PropNames[lPropNum]; break; case 1: // Second language wsCurrentName = g_PropNamesRu[lPropNum]; break; default: return 0; } iActualSize = wcslen(wsCurrentName)+1; if (m_iMemory && wsCurrentName) { if (m_iMemory->AllocMemory((void**)&wsPropName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(&wsPropName, wsCurrentName, iActualSize); } return wsPropName; } //---------------------------------------------------------------------------// bool CAddInNative::GetPropVal(const long lPropNum, tVariant* pvarPropVal) { switch(lPropNum) { case ePropIsInited: TV_VT(pvarPropVal) = VTYPE_BOOL; TV_BOOL(pvarPropVal) = m_boolInited; break; case ePropVersion: TV_VT(pvarPropVal) = VTYPE_PWSTR; pvarPropVal->pwstrVal = m_wstrVersion; pvarPropVal->wstrLen = wcslen(m_wstrVersion); break; case ePropMaxTimeBetweenClicks: TV_VT(pvarPropVal) = VTYPE_I4; TV_I4(pvarPropVal) = m_longMaxTimeBetweenClicks; break; case ePropBufferSize: TV_VT(pvarPropVal) = VTYPE_I4; TV_I4(pvarPropVal) = m_longBufferSize; break; case ePropPrefix: TV_VT(pvarPropVal) = VTYPE_PWSTR; pvarPropVal->pwstrVal = m_wstrPrefix; pvarPropVal->wstrLen = wcslen(m_wstrPrefix); break; case ePropSuffix: TV_VT(pvarPropVal) = VTYPE_PWSTR; pvarPropVal->pwstrVal = m_wstrSuffix; pvarPropVal->wstrLen = wcslen(m_wstrSuffix); break; default: return false; } return true; } //---------------------------------------------------------------------------// bool CAddInNative::SetPropVal(const long lPropNum, tVariant *varPropVal) { switch(lPropNum) { case ePropMaxTimeBetweenClicks: if (TV_VT(varPropVal) != VTYPE_I4) return false; m_longMaxTimeBetweenClicks = TV_I4(varPropVal); break; case ePropPrefix: if (TV_VT(varPropVal) != VTYPE_PWSTR) return false; wcscpy(m_wstrPrefix, varPropVal->pwstrVal); break; case ePropSuffix: if (TV_VT(varPropVal) != VTYPE_PWSTR) return false; wcscpy(m_wstrSuffix, varPropVal->pwstrVal); break; default: return false; } return true; } //---------------------------------------------------------------------------// bool CAddInNative::IsPropReadable(const long lPropNum) { switch(lPropNum) { case ePropIsInited: case ePropVersion: case ePropMaxTimeBetweenClicks: case ePropBufferSize: case ePropPrefix: case ePropSuffix: return true; default: return false; } return false; } //---------------------------------------------------------------------------// bool CAddInNative::IsPropWritable(const long lPropNum) { switch(lPropNum) { case ePropMaxTimeBetweenClicks: case ePropPrefix: case ePropSuffix: return true; default: return false; } return false; } //---------------------------------------------------------------------------// long CAddInNative::GetNMethods() { return eMethLast; } //---------------------------------------------------------------------------// long CAddInNative::FindMethod(const WCHAR_T* wsMethodName) { long plMethodNum = -1; wchar_t* name = 0; ::convFromShortWchar(&name, wsMethodName); plMethodNum = findName(g_MethodNames, name, eMethLast); if (plMethodNum == -1) plMethodNum = findName(g_MethodNamesRu, name, eMethLast); return plMethodNum; } //---------------------------------------------------------------------------// const WCHAR_T* CAddInNative::GetMethodName(const long lMethodNum, const long lMethodAlias) { if (lMethodNum >= eMethLast) return NULL; wchar_t *wsCurrentName = NULL; WCHAR_T *wsMethodName = NULL; int iActualSize = 0; switch(lMethodAlias) { case 0: // First language wsCurrentName = g_MethodNames[lMethodNum]; break; case 1: // Second language wsCurrentName = g_MethodNamesRu[lMethodNum]; break; default: return 0; } iActualSize = wcslen(wsCurrentName)+1; if (m_iMemory && wsCurrentName) { if(m_iMemory->AllocMemory((void**)&wsMethodName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(&wsMethodName, wsCurrentName, iActualSize); } return wsMethodName; } //---------------------------------------------------------------------------// long CAddInNative::GetNParams(const long lMethodNum) { switch(lMethodNum) { case eMethInit: return 4; case eMethDeinit: return 0; case eMethGetBarcode: return 2; default: return 0; } return 0; } //---------------------------------------------------------------------------// bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) { TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) { case eMethInit: { if (lParamNum == 0) { TV_VT(pvarParamDefValue) = VTYPE_I4; TV_I4(pvarParamDefValue) = 0; } else if (lParamNum == 1) { TV_VT(pvarParamDefValue) = VTYPE_I4; TV_I4(pvarParamDefValue) = 0; } else if (lParamNum == 2) { TV_VT(pvarParamDefValue) = VTYPE_PWSTR; pvarParamDefValue->wstrLen = 0; } else if (lParamNum == 3) { TV_VT(pvarParamDefValue) = VTYPE_PWSTR; pvarParamDefValue->wstrLen = 0; } return true; } case eMethDeinit: break; case eMethGetBarcode: { if (lParamNum == 0) { TV_VT(pvarParamDefValue) = VTYPE_I4; TV_I4(pvarParamDefValue) = 0; } else if (lParamNum == 1) { TV_VT(pvarParamDefValue) = VTYPE_PWSTR; pvarParamDefValue->pwstrVal = (wchar_t *)&m_wstrBarcode; pvarParamDefValue->wstrLen = 0; } return true; } default: return false; } return false; } //---------------------------------------------------------------------------// bool CAddInNative::HasRetVal(const long lMethodNum) { switch(lMethodNum) { case eMethInit: case eMethDeinit: case eMethGetBarcode: return true; default: return false; } return false; } //---------------------------------------------------------------------------// bool CAddInNative::CallAsProc(const long lMethodNum, tVariant* paParams, const long lSizeArray) { return true; } //---------------------------------------------------------------------------// bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) { bool ret = false; switch(lMethodNum) { case eMethInit: { TV_VT(pvarRetValue) = VTYPE_BOOL; if (!m_boolInited && lSizeArray == 4 && TV_VT(&paParams[0]) == VTYPE_I4 && TV_VT(&paParams[1]) == VTYPE_I4 && TV_VT(&paParams[2]) == VTYPE_PWSTR && TV_VT(&paParams[3]) == VTYPE_PWSTR) { m_longMaxTimeBetweenClicks = TV_I4(&paParams[0]); m_longBufferSize = TV_I4(&paParams[1]); if (paParams[2].pwstrVal) wcscpy(m_wstrPrefix, paParams[2].pwstrVal); if (paParams[3].pwstrVal) wcscpy(m_wstrSuffix, paParams[3].pwstrVal); if (!cbInit(&bcbuf, m_longBufferSize)) { TV_BOOL(pvarRetValue) = false; return true; } if (!(m_hhookKeyBDHook = (unsigned long)SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId()))) { TV_BOOL(pvarRetValue) = false; return true; } if (!(m_handleThread = (unsigned long)CreateThread(NULL, 0, &ThreadProc, NULL, 0, NULL))) { UnhookWindowsHookEx((HHOOK)m_hhookKeyBDHook); TV_BOOL(pvarRetValue) = false; return true; } m_boolInited = true; TV_BOOL(pvarRetValue) = true; } else { TV_BOOL(pvarRetValue) = false; } return true; } case eMethDeinit: { TV_VT(pvarRetValue) = VTYPE_BOOL; if (m_boolInited) { m_boolThreadExit = true; while(m_boolThreadExit); cbFree(&bcbuf); if (UnhookWindowsHookEx((HHOOK)m_hhookKeyBDHook)) { m_boolInited = false; TV_BOOL(pvarRetValue) = true; } else { TV_BOOL(pvarRetValue) = false; } TV_BOOL(pvarRetValue) = true; } else { TV_BOOL(pvarRetValue) = false; } return true; } case eMethGetBarcode: { TV_VT(pvarRetValue) = VTYPE_BOOL; if (m_boolInited && lSizeArray == 2) { TV_VT(&paParams[0]) = VTYPE_I4; TV_I4(&paParams[0]) = m_longTypeBarcode; TV_VT(&paParams[1]) = VTYPE_PWSTR; paParams[1].pwstrVal = (wchar_t *)&m_wstrBarcode; paParams[1].wstrLen = wcslen(m_wstrBarcode); TV_BOOL(pvarRetValue) = true; } else { TV_BOOL(pvarRetValue) = false; } return true; } default: return false; } return ret; } //---------------------------------------------------------------------------// void CAddInNative::SetLocale(const WCHAR_T* loc) { _wsetlocale(LC_ALL, loc); } ///////////////////////////////////////////////////////////////////////////// // LocaleBase //---------------------------------------------------------------------------// bool CAddInNative::setMemManager(void* mem) { m_iMemory = (IMemoryManager*)mem; return m_iMemory != 0; } //---------------------------------------------------------------------------// void CAddInNative::addError(uint32_t wcode, const wchar_t* source, const wchar_t* descriptor, long code) { if (m_iConnect) { WCHAR_T *err = 0; WCHAR_T *descr = 0; ::convToShortWchar(&err, source); ::convToShortWchar(&descr, descriptor); m_iConnect->AddError(wcode, err, descr, code); delete[] err; delete[] descr; } } //---------------------------------------------------------------------------// long CAddInNative::findName(wchar_t* names[], const wchar_t* name, const uint32_t size) const { long ret = -1; for (uint32_t i = 0; i < size; i++) { if (!wcscmp(names[i], name)) { ret = i; break; } } return ret; } //---------------------------------------------------------------------------// uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, uint32_t len) { if (!len) len = ::wcslen(Source)+1; if (!*Dest) *Dest = new WCHAR_T[len]; WCHAR_T* tmpShort = *Dest; wchar_t* tmpWChar = (wchar_t*) Source; uint32_t res = 0; ::memset(*Dest, 0, len*sizeof(WCHAR_T)); do { *tmpShort++ = (WCHAR_T)*tmpWChar++; ++res; } while (len-- && *tmpWChar); return res; } //---------------------------------------------------------------------------// uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len) { if (!len) len = getLenShortWcharStr(Source)+1; if (!*Dest) *Dest = new wchar_t[len]; wchar_t* tmpWChar = *Dest; WCHAR_T* tmpShort = (WCHAR_T*)Source; uint32_t res = 0; ::memset(*Dest, 0, len*sizeof(wchar_t)); do { *tmpWChar++ = (wchar_t)*tmpShort++; ++res; } while (len-- && *tmpShort); return res; } //---------------------------------------------------------------------------// uint32_t getLenShortWcharStr(const WCHAR_T* Source) { uint32_t res = 0; WCHAR_T *tmpShort = (WCHAR_T*)Source; while (*tmpShort++) ++res; return res; } //---------------------------------------------------------------------------//