Форум TRACE MODE: техническая поддержка   
мой профиль / my profile авторизация / login | регистрация / register | поиск / search | часто задаваемые вопросы / faq | начало / forum home

  Следующая старая тема / next oldest topic   Следующая новая тема / next newest topic
» Форум TRACE MODE: техническая поддержка » ТЕХНИЧЕСКАЯ ПОДДЕРЖКА / TECHNICAL SUPPORT TRACE MODE 5 » Драйверы / Device Drivers » Cобытия Win32 в функциях RWH.dll

   
Автор / Author Тема / Topic: Cобытия Win32 в функциях RWH.dll
Черемнов Дмитрий
Junior Member / Новичок
Участник № / Member № 721


Icon 1 отправлено / posted      Профиль для / Profile for Черемнов Дмитрий           Редактировать/удалить сообщение / Edit/Delete Post 
Добрый день !

Может кто-нибудь подскажет -
как корректно написать код работы с событиями Win32 в функциях RWH.dll
(приветствуется любая реализация - Visual C++, C++Builder, Delphi).
Были попытки:
1. Написать драйвер сетевого обмена (Winsock2).
(событие на прием пакета не обрабатывается).
2. Создать окно (например, окно настройки драйвера).
Окно создается, но 'зависает' (таже проблема, события не обрабатываются). Если же пишем свою обработку событий, то 'подвисает Trace Mode'.
Пример ниже. В Rwh.dll вызов MainFunc().

int TestWndProc(HWND Window, int AMessage, int WParam, int LParam)
{
TMessage AMsg;
HDC hdcHDC;
TPaintStruct PaintStruct;
TRect Rect;
AMsg.Msg = AMessage;
AMsg.WParam = WParam;
AMsg.LParam = LParam;
AMsg.Result = 0;
switch (AMessage) {
case WM_PAINT: {
hdcHDC = BeginPaint(Window,&PaintStruct);
GetClientRect(Window,&Rect);
DrawText(hdcHDC,"Hello World!", -1,&Rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(Window,&PaintStruct);
break;
};
case WM_DESTROY: { PostQuitMessage(0); break; }
default : {
return (DefWindowProc(Window, AMessage, WParam, LParam));
}
}
return AMsg.Result;
}

//---------------------------------------------------------------------------
void MainFunc()
{
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = (WNDPROC)TestWndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(0,IDI_APPLICATION);
WndClass.hCursor = LoadCursor(0,IDC_ARROW);
WndClass.hbrBackground = HBRUSH(WHITE_BRUSH);
WndClass.lpszMenuName = 0;
WndClass.lpszClassName = sClassName;

if (RegisterClass(&WndClass) != 0)
{
hWindow = CreateWindow(sClassName, "Program1",
WS_OVERLAPPEDWINDOW,
100,100,
100,100,
0,0,
hInstance,0);
if (hWindow != 0)
{
ShowWindow(hWindow, CmdShow);
UpdateWindow(hWindow);
while (GetMessage(&msgMessage,0,0,0))
{
TranslateMessage(&msgMessage);
DispatchMessage(&msgMessage);
//где и как требуется передать управление Trace Mode ?
}
exit(msgMessage.wParam);
}
else {
MessageBox(0,"Cannot create window","Error",MB_OK);
}
}
else MessageBox(0,"Cannot register class","Error",MB_OK);
}
//------------------------------------------------

Сообщения / Posts 2 | Из / From: Казахстан  |  IP / IP: IP адрес / IP address | Report this post to a Moderator
АдАстра. Техподдержка
Administrator
Участник № / Member № 4


Icon 1 отправлено / posted      Профиль для / Profile for АдАстра. Техподдержка           Редактировать/удалить сообщение / Edit/Delete Post 
Очередь сообщений создается для каждого потока. В МРВ несколько потоков, в т.ч. один для обработки драйвера rwh, но сам цикл обработки сообщений заключен в сервере МРВ. Теоретически, можно перехватывать оконные сообщения, но тогда скорее всего нарушится синхронизация с МРВ и приложение зависнет (в лучшем случае), или упадет (в худшем).
Можно при старте драйвера rwh_start() создавать свой отдельный поток (см. ф-цию Win32 API CreateThread()) и в нее уже писать свой код, как в MainFunc() из примера. Такой вариант будет работать, но тогда необходимо самому позаботиться о синхронизации, когда МРВ будет останавливаться (rwh_stop), корректно закрывать окно и завершать свой поток.
Не совсем понятно - зачем вообще в работающем МРВ показывать какое-то окно?! Если окно с настройками, то лучше сделать как всегда - настройки вынести в файл, который правится руками (через текстовый редактор), или специальной самописной программой-конфигуратором. Если нужно менять настройки в режиме реального времени, то для этого проще сделать каналы для передачи параметров в драйвер.
Драйверы сетевого обмена с использованием сокетов Winsock2 прекрасно работают, только не нужно делать синхронизацию на основе обработчиков оконных событий!
Например - можно использовать функцию select():

code:
bool Recv(char* rbuf, unsigned int length, unsigned int& actual, int timeout /* ms */)
{
timeval t;
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout - t.tv_sec*1000) * 1000;
fd_set fr;
FD_ZERO(&fr);
FD_SET(_cs, &fr);
unsigned int read = 0;
int n = 0;
while ( read < length )
{
n = select(1, &fr, 0, 0, &t);
if ( n != 1 ) return false; // timeout
//
n = recv(_cs, rbuf + read, length - read, MSG_PEEK);
if (n == SOCKET_ERROR) return false;
for (unsigned int c=read; c<(read+n); c++)
{
if (rbuf[c]=='\r')
{
recv(_cs, rbuf + read, length - read, 0);
actual = read + c + 1;
return true;
}
}
recv(_cs, rbuf + read, length - read, 0);
read += n;
}
return true;
}

Или ioctlsocket() - пример:
code:
	DWORD time_left = receive_wait_time;
DWORD len = 0;
while (time_left > 0)
{
len = 0;
ioctlsocket(source.socket, FIONREAD, &len);
if (len > 0)
break;
time_left -= receive_check_interval;
Sleep(receive_check_interval);
}
if (len == 0)
{
*log << "nothing received" << std::endl;
actual_count = 0;
return 0;
}
int recvd = recv(source.socket, rbuf, to_recv, 0);
if (recvd == SOCKET_ERROR)
{
*log << Logger::error << "recv failed with error " << WSAGetLastError() << std::endl;
actual_count = 0;
log->pop_func_name();
return 0;
}

Какой способ Вы выберете - решать Вам: первый не вызывает Sleep(), поэтому вроде лучше, но второй - тоже нормально работает.
Сообщения / Posts 17321 | Из / From: Россия  |  IP / IP: IP адрес / IP address | Report this post to a Moderator
   

   Закрыть тему / Close Topic   Feature Topic   Переместить топик / Move Topic   Удалить топик / Delete Topic Следующая старая тема / next oldest topic   Следующая новая тема / next newest topic
 - Printer-friendly view of this topic
Перейти к / Hop To


Новости АСУ ТП / News | SCADA / HMI | Обучение / Trainings | Свяжитесь с нами / Contact Us



Powered by Infopop Corporation
UBB.classic™ 6.7.2