AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.06.2004, 20:47   #1  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Обработка событий в Аксапте
Может кто-нибудь имеет опты по обработке системных событий в Аксапте!! Был-бы рад услышать советы на данную тему!
Старый 17.06.2004, 10:39   #2  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Боюсь, что это не возможно.

Обработать системные события можно либо подменив оконную процедуру Аксапты, либо субклассингом. Я не видел в X++ возможностей не для того, ни для другого.
Хотя, технически, если бы разработчики Аксапты хотели бы дать такую экзотическую возможность - думаю это можно было бы реализовать. Например создав callback функции для каждого из событий.

Если не секрет, какое из событий Вы хотите обработать и зачем Вам это нужно ?
Старый 17.06.2004, 11:05   #3  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Цитата:
Если не секрет, какое из событий Вы хотите обработать и зачем Вам это нужно ?
Не секрет http://forum.mazzy.ru/index.php?showtopic=790
Старый 17.06.2004, 11:14   #4  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Не фига не стало ясно.

Цитата:
Рассказываю!! Есть некое оборудование, которое подключается к ПК!) Это оборудование генерит некое событие (прерывание)! Мне нужно его в Аксапте обработать!!
Что за оборудование ? Как оно подключается к ПК ? Может через COM порт ?
Какие события оно генерит ? И вообще - события это или прерывания ?

Хотя могу предложить универсальное решение - можно реализовать промежуточный слой на одном из системных языков программирования (C++, Delphi и.т.д.)
Суть этого слоя - перехват "события" от Вашего оборудования и в ответ на это событие вызов метода Аксапты через COM интерфейс.
В принципе, этот промежуточный слой можно реализовать в виде dll или activeX и использовать прямо в Аксапте. Останется только проблема с развертыванием.
Старый 17.06.2004, 11:22   #5  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Цитата:
Хотя могу предложить универсальное решение - можно реализовать промежуточный слой на одном из системных языков программирования (C++, Delphi и.т.д.)
Такое решение уже есть! Но хотелось бы без "прослоек"! Потому что за этими "прослойками" нужно дополнительно следить: что они стояли у пользователя, чтобы были запущены в нужное время и в нужном месте.
А оборудование до боли просто: сканер штрих-кода!!
Старый 17.06.2004, 11:27   #6  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Еще раз - как подключается оборудование ?

Через COM порт ? Со сканерами штрих-кодов не работал, но с кассовыми аппаратами идет такая вещь, как драйвер - хотя это тоже промежуточное звено, за которым нужно следить, чтобы он был установлен у пользователя.

Пока Вы не скажете более подробную информацию о том, какие события(прерывания) генерит Ваше оборудование - вам вряд ли кто-то поможет.

p.s. Вообще под системными событиями в Windows понимаются константы WM_*, которые определены в файле windows.h. Но как я понял, у Вас все-таки нечто иное
Старый 17.06.2004, 11:31   #7  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Сканер подключается через COM-порт. И мне необходимо при сканировании штрих-кода на упаковке получить этот код в поле формы Аксапты!
Старый 17.06.2004, 11:32   #8  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Dll однозначно. Хотя Axapta, по идее, могла бы понимать такую штуку и сама. Handle'ров нет, напрямую порт хоть и откроешь, но нет доступа к более специфическим функциям (SetCommSpeed, SetCommTimeOut,..) так привычных в C++... Кстати, у меня есть утилита для трансляции из COM в разрыв клавиатуры, но это не выход - криво уж очень...

А чей сканер-то? Metrologic, Symbol, CipherLab, HPP?
Старый 17.06.2004, 11:49   #9  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Цитата:
Сканер подключается через COM-порт.
Ну наконец-то Долго же мне пришлось Вас пытать.

ОК. Шансов не много, но попробовать можно.
Дело в том, что в Windows с COM портом можно работать так же, как и с обычным файлом - через api функцию CreateFile.

Однако есть несколько неприятных моментов:

1) CreateFile реализованная в классе WinApi Вам не подходит.

Вот ее обертка в Аксапте:

PHP код:
client server static int createFile(str fileNameint flags #OPEN_ALWAYS, int access = 0) 
А вот так объявлен ее заголовок в windows.h:

Цитата:
hCom = CreateFile( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices );
То есть, последний параметр, который нам и нужен, в Аксапте отсутствует.
Так что нужно будет реализовать свою версию WinAPI::CreateFile

2. Нужно будет создать свои обертки вокруг API функций GetCommState и SetCommState.

3. Может еще что-то забыл.

p.s. Сам бы я поставил драйвер (или любое другое промежуточное ПО и не мучался).
Старый 17.06.2004, 11:53   #10  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Цитата:
Handle'ров нет, напрямую порт хоть и откроешь, но нет доступа к более специфическим функциям (SetCommSpeed, SetCommTimeOut,..) так привычных в C++...
Вот этого честно говоря не понял....
CreateFile как раз handle и возвращает.

А параметры устройства, как я понимаю можно не определять - Vasilenko Alexsandr их должен знать. Достаточно будет задать их как константы:

PHP код:
  b.BaudRate CBR_9600;     // set the baud rate     
            
b.ByteSize 8;             // data size, xmit, and rcv     
            
b.Parity NOPARITY;        // no parity bit     
            
b.StopBits ONESTOPBIT;    // one stop bit 
Старый 17.06.2004, 11:54   #11  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
PHP код:
static void CreateCommPort(Args _args)
{
    
int     handle;
    ;
    
handle WinAPI::createFile("COM1"31);

    
info(strfmt("%1",handle));

    
WinAPI::closeHandle(handle);

Упс.. Опередили
Старый 17.06.2004, 12:09   #12  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Да, дело в том, что, когда я писал компоненты для работы с подобного рода аппаратурой, (Сканеры, принтеры шк, теминалы), мне приходилось использовать OVERLAPPED.. Хм... что-то вроде..
PHP код:
DWORD    ScannerData(LPVOID lParam);
{
HANDLE    m_hComm;
HANDLE    m_hCancelEvent;
OVERLAPPED ov={0,0,0,0,NULL};
char    m_szData[256];

    
HANDLE waitfor[]={m_hCancelEventov.hEvent};

    
DWORD dwHandleSignaled;

    if(!
ClearCommError(m_hComm,&dwError,&csStat))
    {
        
TRACE(_T("\nerror ClearCommError() %ld"),GetLastError());
        
CloseHandle(ov.hEvent);
        return(
0);
    }
    
//AfxMessageBox(_T("Started!!!"));
    
z=ResetEvent(ov.hEvent);
    if(
z==0)
    {
        
z=GetLastError();
        
//csData.Format(_T("Error:%d"),z);AfxMessageBox(csData);
    
}
    
    
nCount=0;
    for(
z=0;z<1024;z++)szData[z]=' ';szData[z]=0;
    for(
z=0;z<255;z++)szBuffer[z]=' ';szBuffer[z]=0;

    while(
true)
    {
        
ResetEvent(ov.hEvent);
        
ResetEvent(m_hCancelEvent);
        
        if(
WaitCommEvent(m_hComm,&dwEvtMask,&ov)==0)
            {
            
dwHandleSignaled=WaitForMultipleObjects(2,waitfor,FALSE,5000);
            
// Which event occured?
            
switch(dwHandleSignaled)
                {
                    case 
WAIT_OBJECT_0:    //cancelled
                        
{   // Time to exit.
                            //AfxMessageBox(_T("Cancel Event was recieved!"));
                            
CloseHandle(ov.hEvent);
                            return 
0;
                        }
                       case 
WAIT_OBJECT_0 1// ReadEvent signaled.
                        
{
                            
//AfxMessageBox(_T("\nRecieved:"));
                            
ClearCommError(m_hComm,    &dwError, &csStat);
                            
ReadFile(m_hCommszBuffercsStat.cbInQue, &dwBytes, &ov);
                            
//    if (!ReadFile(m_hComm, szBuffer, cst.cbInQue, &dwBytes, &ov))
                            //    {
                            //        if (WaitForMultipleObjects(2, waitfor, FALSE, 2000) == WAIT_OBJECT_0)break;
                            //    }
                            //for (UINT i = 0; i < cst.cbInQue; i++)
                            
for (UINT i 0dwBytesi++)
                                {
                                
szData[nCount++]=szBuffer[i];
                
                    if(
szBuffer[i]==13)
                        {
                            
szData[nCount]=0;
                            
//Получили Ввод, Обработка
                            
nCount 0;
                            for(
z=0;z<1024;z++)szData[z]=' ';szData[z]=0;
                        }
                    }
                    case 
WAIT_TIMEOUT:
                        {
                            
TRACE(_T("."));
                            break;
                        }
                } 
            }
        else
            {
            if (
dwEvtMask EV_BREAK)
                {
                    
//AfxMessageBox(_T("\nBREAK recieved!Ended!!!"));
                    
break;
                }
            else if (
dwEvtMask EV_RXCHAR)
            {
            
            }
            else {
TRACE(_T("\n?"));}
            }
    }
    
CloseHandle(ov.hEvent);
    
ov.hEvent INVALID_HANDLE_VALUE;
    
//AfxMessageBox(_T("The thread if die!"));
    
return(0);

Вот. Я кое-где комменты повбивал и TRACE раскомментировал..
Все это в отдельном потоке крутилось, разумеется..
Старый 17.06.2004, 12:12   #13  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Просто сечас под рукой ничего более приличного нет... Это что-то из старого.. Но, надеюсь, принцип понятен. В Axapte есть, в принципе, потоки... TutorialThread и все такое... но реально не работал, так что не скажу.

В документации - только 1 упоминание о сканере (в торговле и логистике). И то, судя по всему, клавиатурного
Старый 17.06.2004, 12:16   #14  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Уважаемые господа!! Это все хорошо и понятно!! Работать с COM-портом Аксапта может, ура!! Но здесь вожен еще один момент, в Аксапте нужно организовать механизм беспрерывного опроса СOM-порта, чтобы пользователь не сидел и не ждал пока информация из СOM-порта соблаговолит попасть к нему в окно. Здесь важно, что Аксапта среагировала именно в тот момент, кода код считался с помощью сканера!
Старый 17.06.2004, 12:24   #15  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Думаю мы убедили Vasilenko Alexsandr - использовать промежуточное ПО

Хотя, если есть куча свободного времени - почему бы и не попробовать
Старый 17.06.2004, 12:25   #16  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Александр! Так о том и речь, что невозможно открыть СОМ-порт, используя
OVERLAPPED!!

т.е, что бы предыдущий пример заработал, надо, кроме того, что бы поместить его в отдельный поток, еще и открыть порт примерно таким образом:
PHP код:
BOOL CAddIn::InitComm(int nCommPortint nCommSpeed)
{
    
DCB dcb;
    
CString szCommPort;
    
    switch(
nCommPort)
    {
        case 
0:        szCommPort.Format(_T("COM1"));break;
        case 
1:        szCommPort.Format(_T("COM2"));break;
        case 
2:        szCommPort.Format(_T("COM3"));break;
        case 
3:        szCommPort.Format(_T("COM4"));break;
        case 
4:        szCommPort.Format(_T("COM5"));break;
        case 
5:        szCommPort.Format(_T("COM6"));break;
        case 
6:        szCommPort.Format(_T("COM7"));break;
        case 
7:        szCommPort.Format(_T("COM8"));break;
        default:    
szCommPort.Format(_T("COM1"));break;
    }


    
m_hComm CreateFile(szCommPortGENERIC_READ GENERIC_WRITE,
                 
0NULLOPEN_EXISTINGFILE_FLAG_OVERLAPPEDNULL);
    if (::
m_hComm == INVALID_HANDLE_VALUE
    {
        
AfxMessageBox(_T("?хтючьюцэю юЄъЁ?Є№ COM яюЁЄ"));
        return 
FALSE;
    }

    if(
ov.hEvent == INVALID_HANDLE_VALUEov.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
      
    
GetCommState(::m_hComm,&dcb);
    
SetupComm (::m_hComm256256);       // allocate transmit & receive buffer
    
switch(nCommSpeed)
    {
        case 
0:        dcb.BaudRate CBR_115200;break;
        case 
1:        dcb.BaudRate CBR_57600;break;
        case 
2:        dcb.BaudRate CBR_38400;break;
        case 
3:        dcb.BaudRate CBR_19200;break;
        case 
4:        dcb.BaudRate CBR_9600;break;
        case 
5:        dcb.BaudRate CBR_4800;break;
        case 
6:        dcb.BaudRate CBR_2400;break;
        default:    
dcb.BaudRate CBR_9600;break;
    }
    
dcb.ByteSize 8;
    
dcb.Parity NOPARITY;
    
dcb.StopBits ONESTOPBIT;
    
dcb.fRtsControl RTS_CONTROL_ENABLE;
    
SetCommState (::m_hComm, &dcb);
    
SetCommMask(::m_hCommEV_BREAK EV_RXCHAR);

return 
TRUE;

И как Вы собираетесь выставить параметры СОМ порта?
Я, в принципе, знаю, что куда надо записать.... UART он во всем мире одинаков
т.е. как в регистрах UART выставить соответствующие значения? 0011001 (то, что, в принципе и делает SetCommState)
Старый 17.06.2004, 12:26   #17  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
Цитата:
Все это в отдельном потоке крутилось, разумеется..
А вот отсюда можно поподробней?
Как можно рабоать с несколькими потоками в Аксапте, как организвать работу в разных потоках??!
Старый 17.06.2004, 12:28   #18  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Цитата:
Работать с COM-портом Аксапта может, ура!!
Я этого не говорил.

Цитата:
Как можно рабоать с несколькими потоками в Аксапте, как организвать работу в разных потоках??!
Посмотрите форму tutorial_Thread.
Старый 17.06.2004, 12:30   #19  
Vasilenko Alexsandr is offline
Vasilenko Alexsandr
Участник
Дети Юза
 
90 / 16 (1) ++
Регистрация: 05.09.2002
Адрес: Одесса
2 George Nordic: Вы опережаете мои вопросы, спасибо!! Я за Вами не успеваю!!
Старый 17.06.2004, 12:33   #20  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Цитата:
Изначально опубликовано Андре
Думаю мы убедили Vasilenko Alexsandr - использовать промежуточное ПО

Хотя, если есть куча свободного времени - почему бы и не попробовать
Опять опоздал! Андрей, скорость Ваших ответов просто поражает
Полностью с Вами согласен! Александр, эксперементируйте! Только не забудьте поделиться с общественностью Я могу дать пример кода... Хотя, я думаю, на всяких OpenSource'ax их тоже хватает. В любом случае, инструмент для работы с СОМ-портом из Axapta - хорошая штука. Кстати, всякие коммерческие Dll - редкая дрянь (по крайней мере 2 года назад так оно и было).. Черт! Да у меня же своя где-то есть!!! Как раз для работы с торговым оборудованием всяким.. Ох.. надо дома в архивах порыться... а, может, и выложена где на www.CihperLab.ru

Удачи!
С Уважением, Георгий.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Standart Costing, Direct Costing и механизмы их реализации в Аксапте slava09 DAX: Функционал 55 05.06.2006 11:00
Система оповещений в Аксапте (события в Аксапте) raunio DAX: Прочие вопросы 1 29.09.2005 15:44
Аналитический учет в Аксапте. Анна DAX: Прочие вопросы 38 06.04.2005 14:04
Размышления на тему “Системы контроля версий в Аксапте”. Андре DAX: База знаний и проекты 31 07.02.2005 12:29
Обработка событий ячейки грида simply DAX: Программирование 2 24.05.2004 15:36

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:12.