На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Visual Studio 2008 + COM Port
    В С++ Builder 6 создана программа обмена по COM порту в асинхронном режиме. Программа выполнена на трех потоках VinApi. Ничего особенного. Все просто. Основные функции ниже по тексту
    ExpandedWrap disabled
      #include <vcl.h>
      #pragma hdrstop
       
      #include "Unit1.h"
      //---------------------------------------------------------------------------
      #pragma package(smart_init)
      #pragma resource "*.dfm"
      #include <iostream>
      #include <windows.h>
      #include <stdio.h>
      #include <Math.hpp>
      #include <math.h>
       
      TForm1 *Form1;
       
      //---------------------------------------------------------------------------
      // дефайны
       
      //ёмкость буфера приема
      #define BUFSIZE_RD 5000
      //ёмкость буфера передачи
      #define BUFSIZE_WR 128
       
      //---------------------------------------------------------------------------
      // дескрипторы
       
      HANDLE COMport;
      HANDLE writer;
      HANDLE reader;
      HANDLE main;
       
      ///будем использовать для операций чтения (см. поток ReadThread)
      OVERLAPPED overlapped;
      //будем использовать для операций записи (см. поток WriteThread)
      OVERLAPPED overlappedwr;
       
      //---------------------------------------------------------------------------
      // глобальные переменные
       
      // строка определения com порта
      AnsiString com_port;
       
      // флаг приема
      bool FlComRead;
      // флаг цикла в потоке приема
      bool flag;
       
      bool FlBeg;
       
      //приёмный и передающий буферы
      unsigned char bufrd[BUFSIZE_RD], bufwr[BUFSIZE_WR];
      // контрольная сумма пакета передачи
      unsigned char TxBufCrc;
      unsigned char PrCanal;
      unsigned char PrSect;
       
      // счетчик приемов
      unsigned int counterRX;
      unsigned int counterTX;
      unsigned int counterRP;
      unsigned int Dist;
      unsigned int Distm;
       
      // скорость бод
      unsigned long BaudR;
       
      //---------------------------------------------------------------------------
      __fastcall TForm1::TForm1(TComponent* Owner)
              : TForm(Owner)
      {
      }
       
      //---------------------------------------------------------------------------
      // функции
       
      //---------------------------------------------------------------------------
       
      // задержка
      void wait (int wt)
      {
        while (wt--);
      }
       
      //---------------------------------------------------------------------------
      // Принятые байты в HEX
       
      void hexdumpstrRead ( char src[], size_t size)
      {
        Form1->Memo2->Clear();
        static const char hex[] = "0123456789abcdef";
        char *result = (char *)malloc((size > 0)? size*3: 1),
          *p = result;
       
        if (result) {
          while (size-- > 0) {
            *p++ = hex[(*src >> 4) & 0x0f];
            *p++ = hex[*src++ & 0x0f];
            *p++ = ' ';
          }
          p[(p > result)? -1: 0] = 0;
        }
        Form1->Memo2->Lines->Add(result);
      }
      //---------------------------------------------------------------------------
      // Переданные байты в HEX
       
      void hexdumpstrWrite ( char src[], size_t size)
      {
        Form1->Memo1->Clear();
        static const char hex[] = "0123456789abcdef";
        char *result = (char *)malloc((size > 0)? size*3: 1),
          *p = result;
       
        if (result) {
          while (size-- > 0) {
            *p++ = hex[(*src >> 4) & 0x0f];
            *p++ = hex[*src++ & 0x0f];
            *p++ = ' ';
          }
          p[(p > result)? -1: 0] = 0;
        }
        Form1->Memo1->Lines->Add(result);
      }
       
      //---------------------------------------------------------------------------
      // Вывод принятых байтов на экран
       
      void ReadPrinting(DWORD btr)
      {
        char Buffer[20];
        unsigned int nb, tm;
        String stroka, temp_str;
        counterRP++;
      //  sprintf(Buffer," %d", counterRP);
      //  Form1->Label9->Caption = Buffer;
       
        // Перенос буфера в строку.
        for(UINT32 i=0; i<btr ; i++)
        {
          stroka = stroka + IntToHex(bufrd[i], 2) + ' ';
        }
        // кличество принятых байт
      //  Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);
        // контрольные символы
        for (UINT32 i = 0; i < sizeof(bufrd); i++)
        {
          if(bufrd[i] == 0xa1 && bufrd[i + 1] == 0xa2 && !FlBeg)
          {
            FlBeg = 1;
            nb = ((bufrd[i + 2] << 8) | bufrd[i + 3]);
            sprintf(Buffer,"Кол. инфо байт в пакете: %d", nb);
            Form1->Panel2->Caption = Buffer;
            
            Form1->Memo2->Clear();
      //      wait(30000000); // ЗАПЛАТКА.
       
            if(Form1 -> CheckBox4 -> Checked)
              Sleep(100);
            else
              Sleep(400);
       
            Form1->Panel1->Caption = "";
       
      //      if(!FlComRead) FlComRead = 1;
          }
          // определение последнего канала
          else if(bufrd[i] == 0x55 && bufrd[i + 1] == 0xaa && bufrd[i + 3] == 0x75)
          {
            //
            tm = bufrd[i + 6];
      //      Sleep(100);
      //      wait(300000); // ЗАПЛАТКА.
            if(!FlComRead) FlComRead = 1;
            break;
          }
        }
        // количество принятых байт
        Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);
        // Вывод
        Form1->Memo2->Lines->Add(stroka);
        // Очистить буфер (чтобы данные не накладывались друг на друга).
        memset(bufrd, 0, BUFSIZE_RD);
      }
       
      //---------------------------------------------------------------------------
      // Поток чтения
       
      DWORD WINAPI ReadThread( LPVOID lpParam )
      {
        // буфер для вывода строк
        char Buffer[20];
        // структура текущего состояния порта,
        // используется для определения количества принятых в порт байт
        COMSTAT comstat;
        // переменная temp используется в качестве заглушки
        DWORD btr, temp, mask, signal;
        // создать сигнальный объект-событие для асинхронных операций
        overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
        // установить маску на срабатывание по событию приёма байта в порт
        SetCommMask(COMport, EV_RXCHAR);
        // пока поток не будет прерван, выполняем цикл
      //  while(1)
        while(!flag)
        {
          //ожидать события приёма байта (это и есть перекрываемая операция)
          WaitCommEvent(COMport, &mask, &overlapped);
          //приостановить поток до прихода байта
          signal = WaitForSingleObject(overlapped.hEvent, INFINITE);
          //если событие прихода байта произошло
          if(signal == WAIT_OBJECT_0)
          {
            //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
            if(GetOverlappedResult(COMport, &overlapped, &temp, true))
            {
              //если произошло именно событие прихода байта
              if((mask & EV_RXCHAR)!=0)
              {
      //          Sleep(10);
                // нужно заполнить структуру COMSTAT
                ClearCommError(COMport, &temp, &comstat);
                // и получить из неё количество принятых байтов
                btr = comstat.cbInQue;
                // если действительно есть байты для чтения
                if(btr)
                {
      //            Sleep(10);
                  // прочитать байты из порта в буфер программы
                  ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                  // увеличиваем счётчик байтов
                  counterRX+=btr;
      //            sprintf(Buffer," %d", counterRX);
      //            Form1->Label9->Caption = Buffer;
                  // вызываем функцию для вывода данных на экран
                  ReadPrinting(btr);
      //            hexdumpstrRead(bufrd, 846);
                }
              }
            }
          }
        Sleep(1);
        }
        // таймаут потока
      //  Sleep(1);
        CloseHandle(overlapped.hEvent);
      }
       
      //---------------------------------------------------------------------------
      // Поток записи WriteThread
       
      //главная функция потока, выполняет передачу байтов из буфера в COM-порт
      DWORD WINAPI WriteThread(LPVOID lpParam)
      {
        CONST HANDLE hMutex = (CONST HANDLE)lpParam;
       
        // temp - переменная-заглушка
        DWORD temp, signal;
        // текущий рабочий буфер
        char Buffer[20];
       
        //создать событие
        overlappedwr.hEvent = CreateEvent(NULL, true, true, NULL);
        while(1)
        {
          //очистить передающий буфер порта
          PurgeComm(COMport, PURGE_TXCLEAR);
          //записать байты в порт (перекрываемая операция!)
      //    WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);
          WriteFile(COMport, bufwr, sizeof(bufwr), &temp, &overlappedwr);
       
          //приостановить поток, пока не завершится перекрываемая операция WriteFile
          signal = WaitForSingleObject(overlappedwr.hEvent, INFINITE);
       
          //если операция завершилась успешно
          if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(COMport, &overlappedwr, &temp, true)))
          {
            //вывести сообщение об этом в строке состояния
            sprintf(Buffer,"Передача  %d  прошла успешно", counterTX);
            Form1->Panel1->Caption = Buffer;
          }
          //иначе вывести в строке состояния сообщение об ошибке
          else {Form1->Panel1->Caption = "Ошибка передачи";}
          // Приостановить поток записи
          SuspendThread(writer);
        Sleep(1);
        }
        // таймаут в потоке
      //  Sleep(1);
      }
       
      //---------------------------------------------------------------------------
      // Поток main
       
      DWORD WINAPI MainThread(LPVOID lpParam)
      {
        // текущий рабочий буфер
        char Buffer[20];
       
        while(1)
        {
          // если принят пакет
          if(FlComRead)
          {
            FlBeg = 0;
            FlComRead = 0;
       
            sprintf(Buffer,"Дистанция: %d м", Distm);
            Form1->Label16->Caption = Buffer;
       
       
            // включение режима снятия характеристики
            if(Form1->CheckBox1 -> Checked)
            {
              bufwr[126] |= (1 << 7);
              Form1->CSpinEdit3->Enabled = true;
              Form1->CSpinEdit4->Enabled = true;
            }
            else
            {
              bufwr[126] &= ~(1 << 7);
              Form1->CSpinEdit3->Enabled = false;
              Form1->CSpinEdit4->Enabled = false;
            }
       
            // включение режима снятия характеристики
            if(Form1->CheckBox2 -> Checked)
            {
              bufwr[123] |= (1 << 2);
              bufwr[126] = 80;
            }
            else
            {
              bufwr[123] &= ~(1 << 2);
            }
       
            // контрольная сумма в 0
            TxBufCrc = 0;
              // подсчет контрольной суммы пакета управл.
              for(int i = 1; i < 127; i++)
              {
                TxBufCrc = TxBufCrc + bufwr[i];
                }
            // контрольная сумма упр. пакета
            bufwr[127] = TxBufCrc;
            // вывод управл пакета в Memo 1
            hexdumpstrWrite(bufwr,128);
            // номер передачи
            counterTX++;
            // количество принятых байт в 0
            counterRX = 0;
                //чтобы данные не накладывались друг на друга
            //очистить передающий буфер порта
            PurgeComm(COMport, PURGE_TXCLEAR);
       
            // включение передачи
            if(Form1->CheckBox3 -> Checked)
            {
              //активировать поток записи данных в порт
              ResumeThread(writer);
            }
          }
        Sleep(1);
        }
        // таймаут в потоке
      //  Sleep(1);
      }
       
      //---------------------------------------------------------------------------
      // Com установки
       
      void Com_Setting()
      {
        COMMTIMEOUTS timeouts;
       
        com_port += "\\\\.\\";  // com_port.c_str()
        com_port += Form1->ComboBox1->Text;
        COMport = CreateFile(Form1->ComboBox1->Text.c_str(),GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
       
        if(COMport==INVALID_HANDLE_VALUE)
        {
            if(GetLastError()==ERROR_FILE_NOT_FOUND)
            {
                MessageBox(NULL,"serial port does not exist.","",MB_OK);
            }
          MessageBox(NULL,"serial port error","", MB_OK);
        }
       
        DCB dcbSerialParams = {0};
        dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
        if (!GetCommState(COMport, &dcbSerialParams))
        {
            MessageBox(NULL,"getting state error\n","",MB_OK);
        }
        dcbSerialParams.BaudRate=BaudR;
        dcbSerialParams.ByteSize=8;
        dcbSerialParams.StopBits=ONESTOPBIT;
        dcbSerialParams.Parity=NOPARITY;
        if(!SetCommState(COMport, &dcbSerialParams))
        {
            MessageBox(NULL,"error setting serial port state\n","",MB_OK);
        }
       
        // Установка таймаутов.
        timeouts.ReadIntervalTimeout = 10;        // таймаут между двумя символами
        timeouts.ReadTotalTimeoutMultiplier = 0;  // общий таймаут операции чтения
        timeouts.ReadTotalTimeoutConstant = 0;    // константа для общего таймаута операции чтения
        timeouts.WriteTotalTimeoutMultiplier = 0; // общий таймаут операции записи
        timeouts.WriteTotalTimeoutConstant = 0;   // константа для общего таймаута операции записи
       
        // Загрузить структуру таймаутов в порт.
        if(!SetCommTimeouts(COMport, &timeouts))
        {
          // Если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния.
          MessageBox(NULL,"Не удалось установить тайм-ауты\n","",MB_OK);
          return;
        }
       
        // Установить размеры очередей приёма и передачи
        SetupComm(COMport,2000,2000);
        // Очистка буферов порта
        PurgeComm(COMport,PURGE_RXCLEAR);
        // очистить строку имени порта
        com_port = "";
       
      }


    Теперь стоит задаче переместить все в VisualStudio 2008 поскольку к данному коду необходимо будет приклепать сложную графику GLUT.
    Подскажите пожалуйста как данный код заставить работать в VisualStudio 2008? Пока совершенно не врубаюсь каким образом это можно сделать. Пробовал делать в WindowsForm используя компонент serialPort. Может я не прав но похоже полная ерунда. Компонент не приспособлен для асинхронного режима. А нужно повторить именно асинхронный режим COM порта. Это связано с жесткими временными рамками приема и ответной передачи данных.
    Если не сложно, подскажите пожалуйста коротко путь по которому функции данного кода + потоки можно приспособить в WindowsForm VisualStudio 2008.
    Спасибо.
      тупо копипаст не пробовал? :D
        В VisualStudio 2008 можно писать как на практически том же C++, что и Билдере, так и на шарпе.
        Воспроизвести С++ код из Билдера несложно, т.к. в данном случае VCL-ность не задействована (правда, и синхронизации с главным потоком я не заметил)

        Компонент serialPort относится к шарпу, и работает именно асинхронно.
          Для обмена в асинхронном режиме зачем три потока? Ну один, ну два, ну никак не три.

          Можно это в шарпе сделать с SerialPort, легко и удобно, только со сложной графикой windowsforms не очень подходит в плане производительности.
            Спасибо. Если так, тогда как это делается на практике? WindowsForm необходим, поскольку нужен интерфейс с кнопками и окнами вывода информации. Сам интерфейс составить несложно. Не врубаюсь как теперь туда подключить потоки с кодом внутри и необходимыми функциями. Если можно коротко по пунктам как это сделать.
              Поток приёма уже есть внутри serialPort. Его событие DataReceived вызывается из этого (вторичного) потока, так что не забыть про синхронизацию.
                Цитата Acvarif @
                Спасибо. Если так, тогда как это делается на практике? WindowsForm необходим, поскольку нужен интерфейс с кнопками и окнами вывода информации. Сам интерфейс составить несложно. Не врубаюсь как теперь туда подключить потоки с кодом внутри и необходимыми функциями. Если можно коротко по пунктам как это сделать.


                Сделай сначала каркас на шарпе с сериалпортом, чтением записью кнопками, а потом переноси туда свои функции с байтовыми операциями, ну тут рутина, менять кое-что придется, это ты сам.
                  Пробововал serialPort Может толком не разобрался. Но получилась ерунда. Полнейшая временная разсинхронизация. В чем суть. Потоки приема и передачи в программе на Builder жестко привязаны по времени. Тоесть как только закончился прием непрерывного пакета данных формируется флаг разрешения для передачи обратно так называемого пакета управления. Время между окончанием приема и началом обратной передачи должно уложиться в 5..10 ms. Там организован прием по событию прихода байта на порт. Поэтому скорее всего придется запускать подобные потоки в WindowsForm Вопрос. Можно-ли будет встроить в потоки код типа, где имеются функции типа WaitCommEvent и т.п.?
                  ExpandedWrap disabled
                    // буфер для вывода строк
                      char Buffer[20];
                      // структура текущего состояния порта,
                      // используется для определения количества принятых в порт байт
                      COMSTAT comstat;
                      // переменная temp используется в качестве заглушки
                      DWORD btr, temp, mask, signal;
                      // создать сигнальный объект-событие для асинхронных операций
                      overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
                      // установить маску на срабатывание по событию приёма байта в порт
                      SetCommMask(COMport, EV_RXCHAR);
                      // пока поток не будет прерван, выполняем цикл
                    //  while(1)
                      while(!flag)
                      {
                        //ожидать события приёма байта (это и есть перекрываемая операция)
                        WaitCommEvent(COMport, &mask, &overlapped);
                        //приостановить поток до прихода байта
                        signal = WaitForSingleObject(overlapped.hEvent, INFINITE);
                        //если событие прихода байта произошло
                        if(signal == WAIT_OBJECT_0)
                        {
                          //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                          if(GetOverlappedResult(COMport, &overlapped, &temp, true))
                          {
                            //если произошло именно событие прихода байта
                            if((mask & EV_RXCHAR)!=0)
                            {
                    //          Sleep(10);
                              // нужно заполнить структуру COMSTAT
                              ClearCommError(COMport, &temp, &comstat);
                              // и получить из неё количество принятых байтов
                              btr = comstat.cbInQue;
                              // если действительно есть байты для чтения
                              if(btr)
                              {
                    //            Sleep(10);
                                // прочитать байты из порта в буфер программы
                                ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                // увеличиваем счётчик байтов
                                counterRX+=btr;
                    //            sprintf(Buffer," %d", counterRX);
                    //            Form1->Label9->Caption = Buffer;
                                // вызываем функцию для вывода данных на экран
                                ReadPrinting(btr);
                    //            hexdumpstrRead(bufrd, 846);
                              }
                            }
                          }
                        }
                      Sleep(1);

                  Кстати, а почему WindowsForm c графикой GLUT непроизводителен? Что производительнее?
                  Да, вот источник который использовался для построения кода http://piclist.ru/S-COM-THREAD-RUS/S-COM-THREAD-RUS.html#22
                  Сообщение отредактировано: Acvarif -
                    >Пробововал serialPort
                    Как именно пробовал?
                      Цитата Acvarif @
                      Потоки приема и передачи в программе на Builder жестко привязаны по времени. Тоесть как только закончился прием непрерывного пакета данных формируется флаг разрешения для передачи обратно так называемого пакета управления.

                      Вот в этом-то тебе и повезо.
                      Дело в том, что ф-ии ReadFile/WriteFile потоко-не-безопасны.
                      В твоём примере синхронизации я не заметил, т.е. ты фактически
                      синхронизируешь операции общим ходом алгоритма.
                      Значит, что-нибудь когда-нибудь заглючит..
                        Вот поток в котором осуществляется прием пакета с последующей передачей. Прием принимает, но не всегда, а передача идет не сразу за примом. Разрывы большие, не стабильные по времени. Иногда до 1 сек. В то время как обмен между компом и устройством производится один раз в сек.
                        ExpandedWrap disabled
                                 void Form1::ThreadWork(){
                                      buf_rez = Convert::ToInt32( textBox1->Text );      
                           
                                      while(ThreadWork_Stop){
                                          
                                          //this->Invoke(delInstatnce);
                                          mesRead = this->serialPort1->ReadExisting();
                                          BufferSendCom[0] = bit1;
                                          BufferSendCom[1] = bit2;
                                          BufferSendCom[2] = bit3;
                                          //BufferSendCom[3] = bit4;
                                          
                                          BufferSendCom[124] = bit126;
                                          //timer1->Enabled = true;
                                          //this->Invoke(delInstatnce);
                                          if(mesRead->Length > 1 ){
                                              std::cout << Convert::ToInt32(mesRead[0]) << "ddddsdsd" << std::endl;
                           
                                              if( Convert::ToByte(mesRead[0]) == 63){                    
                                                  //form2->Send_Buffer(mesRead);
                                                  for(int i = 0; i <= 127; i++){
                                                      bufer += BufferSendCom[i];
                                                      BF += BufferSendCom[i];
                                                  }
                                                  
                                                      BufferSendCom[127] = bufer;
                                                      BF += BufferSendCom[127];
                                                      this->serialPort1->Write(BF);
                                                      //Show_Send();
                                                      BF = "";
                                                      bufer = NULL;
                                              }
                                          }
                                          //std::cout << "//////////////////////" << std::endl;
                                          //*****************************
                                          mesRead = "";      
                                          Sleep(1100);
                                      }//while
                                      
                              }

                        Да собственно в коде нет ничего секретного, да к тому же он сырой. В срепке проект в архиве. Прикреплённый файлПрикреплённый файлAmuleTest.rar (159,24 Кбайт, скачиваний: 116)
                          похоже, что осуществляется поллинг (опрос, нету ли чего в порту) - это нехорошо. Как уже сказано, у порта есть событие OnDataReceived, ему нужно назначить обработчик, и при получении данных обработчик вызовется (по сути - аналог WaitCommEvent)

                          (и с синхронизхацией опять беда - в поточной, как я понимаю, функции, прямой доступ к GUI Convert::ToInt32( textBox1->Text ))
                            В общих чертах понятно. Если OnDataReceived сработает так как WaitCommEvent то должно быть то, что нужно. Если не сложно, можно пример кода serialPort + OnDataReceived.
                            Да, синхронизация никакая. Буду поправлять. Это второй этам. Пока нужно понять какой дорожкой пойти. Дальше работать с serialPort или..
                                Спасибо. Становится понятней. Для проверки работы по событию сделал так
                                ExpandedWrap disabled
                                  private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e)
                                           {
                                              counterRX++;
                                              std::cout << Convert::ToInt32(counterRX) << std::endl;
                                           }

                                Работает. Счетчик считает событя по очереди как и должно быть.
                                Попробую подключить функцию накопления данных в буфере.

                                Добавлено
                                Для дальнейшей проверки пытаюсь вывести часть принятых по сом данных в окно textBox2 (со свойством Multiline - true)
                                ExpandedWrap disabled
                                  private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e)
                                           {
                                              mesRead = this->serialPort1->ReadExisting();
                                              for (int i = 0; i < 30; i++)
                                              {
                                                  this->textBox2->Text += mesRead[i].ToString()+"\r\n";
                                              }
                                           }

                                Возникает ошибка
                                ExpandedWrap disabled
                                  Cross-thread operation not valid: Control 'textBox2' accessed from a thread other than the thread it was created on.

                                В чем тут хитрость? Почему операция кросс-поточная?
                                  кто-то не читает, что ему пишут, например, в посте #6
                                  http://stackoverflow.com/questions/1159094...r-of-serialport
                                    Спасибо. Понял. Пробую так http://stackoverflow.com/questions/1077536...m-a-thread-othe Только у меня очевидно проблемы с синтаксисом в VisualStudio2008
                                    ExpandedWrap disabled
                                      delegate void SetTextCallback(string text);
                                       
                                      private: System::Void  SetText(string text)
                                      {
                                        // InvokeRequired required compares the thread ID of the
                                        // calling thread to the thread ID of the creating thread.
                                        // If these threads are different, it returns true.
                                        if (this->textBox2->InvokeRequired)
                                        {
                                          SetTextCallback d = new SetTextCallback(SetText);
                                          this->Invoke(d, new object[] { text });
                                        }
                                        else
                                        {
                                          this->textBox2->Text = text;
                                        }
                                      }
                                       
                                      private: System::Void serialPort1_DataReceived(System::Object^  sender, System::IO::Ports::SerialDataReceivedEventArgs^  e)
                                               {
                                                  txt += serialPort1.ReadExisting().ToString();
                                                  SetText(txt.ToString());
                                               }

                                    Такой код выдает ошибки
                                    ExpandedWrap disabled
                                      Error   1   error C3149: 'AmuleTest::Form1::SetTextCallback' : cannot use this type here without a top-level '^'    d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 984 AmuleTest
                                      Error   2   error C3867: 'AmuleTest::Form1::SetText': function call missing argument list; use '&AmuleTest::Form1::SetText' to create a pointer to member   d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 984 AmuleTest
                                      Error   3   error C2750: 'AmuleTest::Form1::SetTextCallback' : cannot use 'new' on the reference type; use 'gcnew' instead  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 984 AmuleTest
                                      Error   4   error C3350: 'AmuleTest::Form1::SetTextCallback' : a delegate constructor expects 2 argument(s) d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 984 AmuleTest
                                      Error   5   error C2061: syntax error : identifier 'object' d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 985 AmuleTest
                                      Error   6   error C2143: syntax error : missing ')' before '{'  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 985 AmuleTest
                                      Error   7   error C2143: syntax error : missing ';' before '{'  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 985 AmuleTest
                                      Error   8   error C2143: syntax error : missing ';' before '}'  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 985 AmuleTest
                                      Error   9   error C2059: syntax error : ')' d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 985 AmuleTest
                                      Error   10  error C2664: 'void System::Windows::Forms::Control::Text::set(System::String ^)' : cannot convert parameter 1 from 'std::string' to 'System::String ^'  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 989 AmuleTest
                                      Error   11  error C2065: 'txt' : undeclared identifier  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 995 AmuleTest
                                      Error   12  error C2228: left of '.ReadExisting' must have class/struct/union   d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 995 AmuleTest
                                      Error   13  error C2228: left of '.ToString' must have class/struct/union   d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 995 AmuleTest
                                      Error   14  error C2065: 'txt' : undeclared identifier  d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 996 AmuleTest
                                      Error   15  error C2228: left of '.ToString' must have class/struct/union   d:\mydesignsxp\visualstprj\visualc++prj\amuletest\amuletest\Form1.h 996 AmuleTest
                                      ну ты и чайник :D
                                        Сделал небольшой тест на C#
                                        ExpandedWrap disabled
                                          using System;
                                          using System.Collections.Generic;
                                          using System.ComponentModel;
                                          using System.Data;
                                          using System.Drawing;
                                          using System.Linq;
                                          using System.Text;
                                          using System.Windows.Forms;
                                          using System.Threading;
                                           
                                          namespace CrossThreadDemo
                                          {
                                              public partial class Form1 : Form
                                              {
                                                  String txt;
                                                  int counterRP;
                                           
                                                  void ComSetings(){
                                           
                                                      this.serialPort1.BaudRate = 115200;
                                                      this.serialPort1.PortName = "COM1";
                                                      this.serialPort1.ReadBufferSize = 4800;
                                           
                                                      try{
                                                          this.serialPort1.Open();
                                                          this.label1.BackColor = System.Drawing.Color.Green;
                                           
                                                      }
                                                      catch
                                                      {
                                                          this.label1.BackColor = System.Drawing.Color.Red;
                                                      }
                                                  }
                                           
                                                  void StopCom(){
                                                      this.serialPort1.Close();
                                                      this.label1.BackColor = System.Drawing.Color.Red;
                                                  }
                                           
                                                  delegate void SetTextCallback(string text);
                                           
                                                  private void SetText(string text)
                                                  {
                                                      // InvokeRequired required compares the thread ID of the
                                                      // calling thread to the thread ID of the creating thread.
                                                      // If these threads are different, it returns true.
                                                      if (this.textBox1.InvokeRequired)
                                                      {
                                                          SetTextCallback d = new SetTextCallback(SetText);
                                                          this.Invoke(d, new object[] { text });
                                                      }
                                                      else
                                                      {
                                                          this.textBox1.Text = text;
                                                      }
                                                  }
                                                  public Form1()
                                                  {
                                                      InitializeComponent();
                                                  }
                                           
                                                  private void Form1_Load(object sender, EventArgs e)
                                                  {
                                           
                                                  }
                                           
                                                  private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
                                                  {
                                                      txt = serialPort1.ReadExisting().ToString();
                                                      SetText(txt);
                                                  }
                                           
                                                  private void button1_Click(object sender, EventArgs e)
                                                  {
                                                      ComSetings();
                                                  }
                                           
                                                  private void button2_Click(object sender, EventArgs e)
                                                  {
                                                      StopCom();
                                                  }
                                              }
                                          }

                                        Работает. В окне textBox1 передаваемая строка. Но опять проблема. Как теперь в окне textBox1 показать принимаемые данные в HEX виде, примерно так как в программе на Builder
                                        Прикреплённая картинка
                                        Прикреплённая картинка

                                        Еще загвоздка. Как по собитию прихода очередного байта получить количество уже пришедших на порт байт?
                                        WinApi это просто
                                        ExpandedWrap disabled
                                                 //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                                                if(GetOverlappedResult(COMport, &overlapped, &temp, true))
                                                {
                                                  //если произошло именно событие прихода байта
                                                  if((mask & EV_RXCHAR)!=0)
                                                  {
                                                    // нужно заполнить структуру COMSTAT
                                                    ClearCommError(COMport, &temp, &comstat);
                                                    // и получить из неё количество принятых байтов
                                                    btr = comstat.cbInQue;
                                                    // если действительно есть байты для чтения
                                                    if(btr)
                                                    {
                                                      // прочитать байты из порта в буфер программы
                                                      ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                                      // увеличиваем счётчик байтов
                                                      counterRX+=btr;
                                                      // вызываем функцию для вывода данных на экран
                                                      ReadPrinting(btr);
                                                    }
                                                  }
                                                }
                                        Сообщение отредактировано: Acvarif -
                                          да какой С# здесь раздел Visual С++ MFC :D
                                          я твой пример тупо копипаст + MFC и все :D
                                            Копипаст это как? Что такое копипаст?
                                            Поясните пожалуйста.
                                            Это типа ворованный код?
                                            Код проги на Builder мой Прикреплённый файлПрикреплённый файлTest.rar (11,68 Кбайт, скачиваний: 72) . Прога работает без проблем, кроме одной - тяжело работать с графикой OpenGl. Поэтому пытаюсь перевести все в VisualStudio. C# или C++ без разницы. Если у Вас имеется пример как в Visual Studio работать с VinApi и COM портом могли-бы поделиться...
                                            Сообщение отредактировано: Acvarif -
                                              Цитата Acvarif @
                                              Еще загвоздка. Как по собитию прихода очередного байта получить количество уже пришедших на порт байт?
                                              WinApi это просто
                                              ExpandedWrap disabled
                                                       //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                                                      if(GetOverlappedResult(COMport, &overlapped, &temp, true))
                                                      {
                                                        //если произошло именно событие прихода байта
                                                        if((mask & EV_RXCHAR)!=0)
                                                        {
                                                          // нужно заполнить структуру COMSTAT
                                                          ClearCommError(COMport, &temp, &comstat);
                                                          // и получить из неё количество принятых байтов
                                                          btr = comstat.cbInQue;
                                                          // если действительно есть байты для чтения
                                                          if(btr)
                                                          {
                                                            // прочитать байты из порта в буфер программы
                                                            ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                                            // увеличиваем счётчик байтов
                                                            counterRX+=btr;
                                                            // вызываем функцию для вывода данных на экран
                                                            ReadPrinting(btr);
                                                          }
                                                        }
                                                      }

                                              Нет.
                                              Содержимое "overlapped" структуры прямо указывает на переданное количество байт.
                                              "GetOverlappedResult" потрошит эту структуру, хотя это можно было делать и вручную.

                                              Но поскольку конкретная структура использовалась для операции чтения, значит
                                              "GetOverlappedResult(COMport, &overlapped, &Bytes, true)"
                                              сразу передаёт число полученных байт, готовых для чтения.
                                              Дальше:
                                              ExpandedWrap disabled
                                                if(Bytes)
                                                {
                                                 // ...
                                                 /// добываем данные - в указанном операцией ReadFile (выполненной ранее) буфере
                                                 /// есть количество "Bytes" байт, полученных с порта
                                                 
                                                }
                                                Спасибо. Понятно. Можно и так попробовать. В любом случае код Builder6 + WinApi работает без проблем. Перенос кода на VisualStudio нужен для дальнейшей работы с GLUT. На Builder6 с этим делом неважно. Поэтому и прощупываю варианты. Вариант с serialPort на первый взгляд работает. Но опять уткнулся в проблему подсчета и отображения принятых байт в HEX виде в окне textBox. Хотя строку принимает и отображает как надо. По ходу еще проблема как очищать окно textBox перед очередным приемом пакета байт. (период прихода пакетов 1 сек.)

                                                И все же главный вопрос. Можно-ли в VisualStudio использовать непосредственно функции WaitCommEvent(COMport, &mask, &overlapped) GetOverlappedResult(COMport, &overlapped, &Bytes, true); и им подобные? Если да то несколько слов о том как. Какой вид проекта для этого закладывать WindowsForm C++, MFC, win32... ?
                                                Сообщение отредактировано: Acvarif -
                                                  Цитата Acvarif @
                                                  И все же главный вопрос. Можно-ли в VisualStudio использовать непосредственно функции WaitCommEvent(COMport, &mask, &overlapped) GetOverlappedResult(COMport, &overlapped, &Bytes, true); и им подобные? Если да то несколько слов о том как. Какой вид проекта для этого закладывать WindowsForm C++, MFC, win32... ?

                                                  Естествено это же Win32 API! MFC в зубы и вперед с песней! :D
                                                  WinForms это для .NET и C#
                                                    В зубы это да. Какую библиотеку подключить? Куда подключить? Можно несколько слов, коротко, по шагам.
                                                      Цитата Acvarif @
                                                      И все же главный вопрос. Можно-ли в VisualStudio использовать непосредственно функции WaitCommEvent(COMport, &mask, &overlapped) GetOverlappedResult(COMport, &overlapped, &Bytes, true); и им подобные? Если да то несколько слов о том как. Какой вид проекта для этого закладывать WindowsForm C++, MFC, win32... ?

                                                      Да, конечно можно.
                                                      Только "WaitCommEvent" практически не нужна.

                                                      Для ожидания событий достаточно использовать штатные
                                                      функции ожидания Виндус.
                                                      Общая схема такая:
                                                      1. Открываем порт в режиме "OVERLAPPED"
                                                      2. Заполняем все какие надо структуры, программируем ими порт.
                                                      3. Не забываем создать объекты-эвенты.
                                                      4. Хэндлы этих объектов заносятся в OVERLAPPED-структуру перед
                                                      выполнением конкретной операции (чтения или записи).
                                                      5. Дальше эти хэндлы массивом отдаём "WaitForMultipleObjects".
                                                      6. Когда событие наступит, ожидание закончится. Запустим соотв. обработчик.
                                                      7. Распотрошим результат из OVERLAPPED-структуры и начнём всё сначала.

                                                      Как-то так. Одного потока более чем достаточно.
                                                      Почитай книгу Агурова.
                                                      Там хотя и на Паскале, но по API-вызовам понятно, что он делает.
                                                      ---
                                                      Лично я использую базовый класс COMM-порт, использующий WINAPI. (с++)
                                                      После изготовления он занесён в библиотеку, после чего о тонкостях его
                                                      функционирования можно забыть. Именно поэтому мой рассказ о том,
                                                      "как это работает" носит самый общий характер.
                                                      На его основе (наследуясь от него) делается класс COMM-порт для конкретных нужд
                                                      конкретного приложения.
                                                      Сообщение отредактировано: ЫукпШ -
                                                        Все примерно то же самое я уже делал в проге на Builder6. Правда потоков несколько. Может и лишнее. Все работает.
                                                        Я не врубаюсь как код с WINAPI прописать в Wisual Studio. Какой вид проекта для этого открыть MFC, WindovsForm, или...?
                                                        Собственно мой вопрос не по сути, а по технологии. С хендлами, событиями и т. п справлюсь.
                                                        Если начинать проект MFC то куда и чего прописывать
                                                        Напнример в Builder все прописывается в одном едиственном модуле c расширением .cpp
                                                        ExpandedWrap disabled
                                                          #include <vcl.h>
                                                          #pragma hdrstop
                                                           
                                                          #include "Unit1.h"
                                                          //---------------------------------------------------------------------------
                                                          #pragma package(smart_init)
                                                          #pragma resource "*.dfm"
                                                          #include <iostream>
                                                          #include <windows.h>
                                                          #include <stdio.h>
                                                          #include <Math.hpp>
                                                          #include <math.h>
                                                           
                                                          TForm1 *Form1;
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // дефайны
                                                           
                                                          //ёмкость буфера приема
                                                          #define BUFSIZE_RD 5000
                                                          //ёмкость буфера передачи
                                                          #define BUFSIZE_WR 128
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // дескрипторы
                                                           
                                                          HANDLE COMport;
                                                          HANDLE writer;
                                                          HANDLE reader;
                                                          HANDLE main;
                                                           
                                                          ///будем использовать для операций чтения (см. поток ReadThread)
                                                          OVERLAPPED overlapped;
                                                          //будем использовать для операций записи (см. поток WriteThread)
                                                          OVERLAPPED overlappedwr;
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // глобальные переменные
                                                           
                                                          // строка определения com порта
                                                          AnsiString com_port;
                                                           
                                                          // флаг приема
                                                          bool FlComRead;
                                                          // флаг цикла в потоке приема
                                                          bool flag;
                                                           
                                                          bool FlBeg;
                                                           
                                                          //приёмный и передающий буферы
                                                          unsigned char bufrd[BUFSIZE_RD], bufwr[BUFSIZE_WR];
                                                          // контрольная сумма пакета передачи
                                                          unsigned char TxBufCrc;
                                                          unsigned char PrCanal;
                                                          unsigned char PrSect;
                                                           
                                                          // счетчик приемов
                                                          unsigned int counterRX;
                                                          unsigned int counterTX;
                                                          unsigned int counterRP;
                                                          unsigned int Dist;
                                                          unsigned int Distm;
                                                           
                                                          // скорость бод
                                                          unsigned long BaudR;
                                                           
                                                          //---------------------------------------------------------------------------
                                                          __fastcall TForm1::TForm1(TComponent* Owner)
                                                                  : TForm(Owner)
                                                          {
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // функции
                                                           
                                                          //---------------------------------------------------------------------------
                                                           
                                                          // задержка
                                                          void wait (int wt)
                                                          {
                                                            while (wt--);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Принятые байты в HEX
                                                           
                                                          void hexdumpstrRead ( char src[], size_t size)
                                                          {
                                                            Form1->Memo2->Clear();
                                                            static const char hex[] = "0123456789abcdef";
                                                            char *result = (char *)malloc((size > 0)? size*3: 1),
                                                              *p = result;
                                                           
                                                            if (result) {
                                                              while (size-- > 0) {
                                                                *p++ = hex[(*src >> 4) & 0x0f];
                                                                *p++ = hex[*src++ & 0x0f];
                                                                *p++ = ' ';
                                                              }
                                                              p[(p > result)? -1: 0] = 0;
                                                            }
                                                            Form1->Memo2->Lines->Add(result);
                                                          }
                                                          //---------------------------------------------------------------------------
                                                          // Переданные байты в HEX
                                                           
                                                          void hexdumpstrWrite ( char src[], size_t size)
                                                          {
                                                            Form1->Memo1->Clear();
                                                            static const char hex[] = "0123456789abcdef";
                                                            char *result = (char *)malloc((size > 0)? size*3: 1),
                                                              *p = result;
                                                           
                                                            if (result) {
                                                              while (size-- > 0) {
                                                                *p++ = hex[(*src >> 4) & 0x0f];
                                                                *p++ = hex[*src++ & 0x0f];
                                                                *p++ = ' ';
                                                              }
                                                              p[(p > result)? -1: 0] = 0;
                                                            }
                                                            Form1->Memo1->Lines->Add(result);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Вывод принятых байтов на экран
                                                           
                                                          void ReadPrinting(DWORD btr)
                                                          {
                                                            char Buffer[20];
                                                            unsigned int nb, tm;
                                                            String stroka, temp_str;
                                                            counterRP++;
                                                          //  sprintf(Buffer," %d", counterRP);
                                                          //  Form1->Label9->Caption = Buffer;
                                                           
                                                            // Перенос буфера в строку.
                                                            for(UINT32 i=0; i<btr ; i++)
                                                            {
                                                              stroka = stroka + IntToHex(bufrd[i], 2) + ' ';
                                                            }
                                                            // кличество принятых байт
                                                          //  Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);
                                                            // контрольные символы
                                                            for (UINT32 i = 0; i < sizeof(bufrd); i++)
                                                            {
                                                              if(bufrd[i] == 0xa1 && bufrd[i + 1] == 0xa2 && !FlBeg)
                                                              {
                                                                FlBeg = 1;
                                                                nb = ((bufrd[i + 2] << 8) | bufrd[i + 3]);
                                                                sprintf(Buffer,"Кол. инфо байт в пакете: %d", nb);
                                                                Form1->Panel2->Caption = Buffer;
                                                                
                                                                Form1->Memo2->Clear();
                                                          //      wait(30000000); // ЗАПЛАТКА.
                                                           
                                                                if(Form1 -> CheckBox4 -> Checked)
                                                                  Sleep(100);
                                                                else
                                                                  Sleep(400);
                                                           
                                                                Form1->Panel1->Caption = "";
                                                           
                                                          //      if(!FlComRead) FlComRead = 1;
                                                              }
                                                              // определение последнего канала
                                                              else if(bufrd[i] == 0x55 && bufrd[i + 1] == 0xaa && bufrd[i + 3] == 0x75)
                                                              {
                                                                //
                                                                tm = bufrd[i + 6];
                                                          //      Sleep(100);
                                                          //      wait(300000); // ЗАПЛАТКА.
                                                                if(!FlComRead) FlComRead = 1;
                                                                break;
                                                              }
                                                            }
                                                            // количество принятых байт
                                                            Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);
                                                            // Вывод
                                                            Form1->Memo2->Lines->Add(stroka);
                                                            // Очистить буфер (чтобы данные не накладывались друг на друга).
                                                            memset(bufrd, 0, BUFSIZE_RD);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Поток чтения
                                                           
                                                          DWORD WINAPI ReadThread( LPVOID lpParam )
                                                          {
                                                            // буфер для вывода строк
                                                            char Buffer[20];
                                                            // структура текущего состояния порта,
                                                            // используется для определения количества принятых в порт байт
                                                            COMSTAT comstat;
                                                            // переменная temp используется в качестве заглушки
                                                            DWORD btr, temp, mask, signal;
                                                            // создать сигнальный объект-событие для асинхронных операций
                                                            overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
                                                            // установить маску на срабатывание по событию приёма байта в порт
                                                            SetCommMask(COMport, EV_RXCHAR);
                                                            // пока поток не будет прерван, выполняем цикл
                                                          //  while(1)
                                                            while(!flag)
                                                            {
                                                              //ожидать события приёма байта (это и есть перекрываемая операция)
                                                              WaitCommEvent(COMport, &mask, &overlapped);
                                                              //приостановить поток до прихода байта
                                                              signal = WaitForSingleObject(overlapped.hEvent, INFINITE);
                                                              //если событие прихода байта произошло
                                                              if(signal == WAIT_OBJECT_0)
                                                              {
                                                                //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                                                                if(GetOverlappedResult(COMport, &overlapped, &temp, true))
                                                                {
                                                                  //если произошло именно событие прихода байта
                                                                  if((mask & EV_RXCHAR)!=0)
                                                                  {
                                                          //          Sleep(10);
                                                                    // нужно заполнить структуру COMSTAT
                                                                    ClearCommError(COMport, &temp, &comstat);
                                                                    // и получить из неё количество принятых байтов
                                                                    btr = comstat.cbInQue;
                                                                    // если действительно есть байты для чтения
                                                                    if(btr)
                                                                    {
                                                          //            Sleep(10);
                                                                      // прочитать байты из порта в буфер программы
                                                                      ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                                                      // увеличиваем счётчик байтов
                                                                      counterRX+=btr;
                                                          //            sprintf(Buffer," %d", counterRX);
                                                          //            Form1->Label9->Caption = Buffer;
                                                                      // вызываем функцию для вывода данных на экран
                                                                      ReadPrinting(btr);
                                                          //            hexdumpstrRead(bufrd, 846);
                                                                    }
                                                                  }
                                                                }
                                                              }
                                                            Sleep(1);
                                                            }
                                                            // таймаут потока
                                                          //  Sleep(1);
                                                            CloseHandle(overlapped.hEvent);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Поток записи WriteThread
                                                           
                                                          //главная функция потока, выполняет передачу байтов из буфера в COM-порт
                                                          DWORD WINAPI WriteThread(LPVOID lpParam)
                                                          {
                                                            CONST HANDLE hMutex = (CONST HANDLE)lpParam;
                                                           
                                                            // temp - переменная-заглушка
                                                            DWORD temp, signal;
                                                            // текущий рабочий буфер
                                                            char Buffer[20];
                                                           
                                                            //создать событие
                                                            overlappedwr.hEvent = CreateEvent(NULL, true, true, NULL);
                                                            while(1)
                                                            {
                                                              //очистить передающий буфер порта
                                                              PurgeComm(COMport, PURGE_TXCLEAR);
                                                              //записать байты в порт (перекрываемая операция!)
                                                          //    WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);
                                                              WriteFile(COMport, bufwr, sizeof(bufwr), &temp, &overlappedwr);
                                                           
                                                              //приостановить поток, пока не завершится перекрываемая операция WriteFile
                                                              signal = WaitForSingleObject(overlappedwr.hEvent, INFINITE);
                                                           
                                                              //если операция завершилась успешно
                                                              if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(COMport, &overlappedwr, &temp, true)))
                                                              {
                                                                //вывести сообщение об этом в строке состояния
                                                                sprintf(Buffer,"Передача  %d  прошла успешно", counterTX);
                                                                Form1->Panel1->Caption = Buffer;
                                                              }
                                                              //иначе вывести в строке состояния сообщение об ошибке
                                                              else {Form1->Panel1->Caption = "Ошибка передачи";}
                                                              // Приостановить поток записи
                                                              SuspendThread(writer);
                                                            Sleep(1);
                                                            }
                                                            // таймаут в потоке
                                                          //  Sleep(1);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Поток main
                                                           
                                                          DWORD WINAPI MainThread(LPVOID lpParam)
                                                          {
                                                            // текущий рабочий буфер
                                                            char Buffer[20];
                                                           
                                                            while(1)
                                                            {
                                                              // если принят пакет
                                                              if(FlComRead)
                                                              {
                                                                FlBeg = 0;
                                                                FlComRead = 0;
                                                           
                                                                sprintf(Buffer,"Дистанция: %d м", Distm);
                                                                Form1->Label16->Caption = Buffer;
                                                           
                                                           
                                                                // включение режима снятия характеристики
                                                                if(Form1->CheckBox1 -> Checked)
                                                                {
                                                                  bufwr[126] |= (1 << 7);
                                                                  Form1->CSpinEdit3->Enabled = true;
                                                                  Form1->CSpinEdit4->Enabled = true;
                                                                }
                                                                else
                                                                {
                                                                  bufwr[126] &= ~(1 << 7);
                                                                  Form1->CSpinEdit3->Enabled = false;
                                                                  Form1->CSpinEdit4->Enabled = false;
                                                                }
                                                           
                                                                // включение режима снятия характеристики
                                                                if(Form1->CheckBox2 -> Checked)
                                                                {
                                                                  bufwr[123] |= (1 << 2);
                                                                  bufwr[126] = 80;
                                                                }
                                                                else
                                                                {
                                                                  bufwr[123] &= ~(1 << 2);
                                                                }
                                                           
                                                                // контрольная сумма в 0
                                                                TxBufCrc = 0;
                                                                  // подсчет контрольной суммы пакета управл.
                                                                  for(int i = 1; i < 127; i++)
                                                                  {
                                                                    TxBufCrc = TxBufCrc + bufwr[i];
                                                                    }
                                                                // контрольная сумма упр. пакета
                                                                bufwr[127] = TxBufCrc;
                                                                // вывод управл пакета в Memo 1
                                                                hexdumpstrWrite(bufwr,128);
                                                                // номер передачи
                                                                counterTX++;
                                                                // количество принятых байт в 0
                                                                counterRX = 0;
                                                                    //чтобы данные не накладывались друг на друга
                                                                //очистить передающий буфер порта
                                                                PurgeComm(COMport, PURGE_TXCLEAR);
                                                           
                                                                // включение передачи
                                                                if(Form1->CheckBox3 -> Checked)
                                                                {
                                                                  //активировать поток записи данных в порт
                                                                  ResumeThread(writer);
                                                                }
                                                              }
                                                            Sleep(1);
                                                            }
                                                            // таймаут в потоке
                                                          //  Sleep(1);
                                                          }
                                                           
                                                          //---------------------------------------------------------------------------
                                                          // Com установки
                                                           
                                                          void Com_Setting()
                                                          {
                                                            COMMTIMEOUTS timeouts;
                                                           
                                                            com_port += "\\\\.\\";  // com_port.c_str()
                                                            com_port += Form1->ComboBox1->Text;
                                                            COMport = CreateFile(Form1->ComboBox1->Text.c_str(),GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                                                           
                                                            if(COMport==INVALID_HANDLE_VALUE)
                                                            {
                                                                if(GetLastError()==ERROR_FILE_NOT_FOUND)
                                                                {
                                                                    MessageBox(NULL,"serial port does not exist.","",MB_OK);
                                                                }
                                                              MessageBox(NULL,"serial port error","", MB_OK);
                                                            }
                                                           
                                                            DCB dcbSerialParams = {0};
                                                            dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
                                                            if (!GetCommState(COMport, &dcbSerialParams))
                                                            {
                                                                MessageBox(NULL,"getting state error\n","",MB_OK);
                                                            }
                                                            dcbSerialParams.BaudRate=BaudR;
                                                            dcbSerialParams.ByteSize=8;
                                                            dcbSerialParams.StopBits=ONESTOPBIT;
                                                            dcbSerialParams.Parity=NOPARITY;
                                                            if(!SetCommState(COMport, &dcbSerialParams))
                                                            {
                                                                MessageBox(NULL,"error setting serial port state\n","",MB_OK);
                                                            }
                                                           
                                                            // Установка таймаутов.
                                                            timeouts.ReadIntervalTimeout = 10;        // таймаут между двумя символами
                                                            timeouts.ReadTotalTimeoutMultiplier = 0;  // общий таймаут операции чтения
                                                            timeouts.ReadTotalTimeoutConstant = 0;    // константа для общего таймаута операции чтения
                                                            timeouts.WriteTotalTimeoutMultiplier = 0; // общий таймаут операции записи
                                                            timeouts.WriteTotalTimeoutConstant = 0;   // константа для общего таймаута операции записи
                                                           
                                                            // Загрузить структуру таймаутов в порт.
                                                            if(!SetCommTimeouts(COMport, &timeouts))
                                                            {
                                                              // Если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния.
                                                              MessageBox(NULL,"Не удалось установить тайм-ауты\n","",MB_OK);
                                                              return;
                                                            }
                                                           
                                                            // Установить размеры очередей приёма и передачи
                                                            SetupComm(COMport,2000,2000);
                                                            // Очистка буферов порта
                                                            PurgeComm(COMport,PURGE_RXCLEAR);
                                                            // очистить строку имени порта
                                                            com_port = "";
                                                           
                                                          }


                                                        Пытаюсь создать проект MFC Создается модуль .cpp с кодом типа
                                                        ExpandedWrap disabled
                                                          // MFCtest.cpp : Defines the class behaviors for the application.
                                                          //
                                                           
                                                          #include "stdafx.h"
                                                          #include "MFCtest.h"
                                                          #include "MFCtestDlg.h"
                                                           
                                                          #ifdef _DEBUG
                                                          #define new DEBUG_NEW
                                                          #endif
                                                           
                                                           
                                                          // CMFCtestApp
                                                           
                                                          BEGIN_MESSAGE_MAP(CMFCtestApp, CWinApp)
                                                              ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
                                                          END_MESSAGE_MAP()
                                                           
                                                           
                                                          // CMFCtestApp construction
                                                           
                                                          CMFCtestApp::CMFCtestApp()
                                                          {
                                                              // TODO: add construction code here,
                                                              // Place all significant initialization in InitInstance
                                                          }
                                                           
                                                           
                                                          // The one and only CMFCtestApp object
                                                           
                                                          CMFCtestApp theApp;
                                                           
                                                           
                                                          // CMFCtestApp initialization
                                                           
                                                          BOOL CMFCtestApp::InitInstance()
                                                          {
                                                              // InitCommonControlsEx() is required on Windows XP if an application
                                                              // manifest specifies use of ComCtl32.dll version 6 or later to enable
                                                              // visual styles.  Otherwise, any window creation will fail.
                                                              INITCOMMONCONTROLSEX InitCtrls;
                                                              InitCtrls.dwSize = sizeof(InitCtrls);
                                                              // Set this to include all the common control classes you want to use
                                                              // in your application.
                                                              InitCtrls.dwICC = ICC_WIN95_CLASSES;
                                                              InitCommonControlsEx(&InitCtrls);
                                                           
                                                              CWinApp::InitInstance();
                                                           
                                                              AfxEnableControlContainer();
                                                           
                                                              // Standard initialization
                                                              // If you are not using these features and wish to reduce the size
                                                              // of your final executable, you should remove from the following
                                                              // the specific initialization routines you do not need
                                                              // Change the registry key under which our settings are stored
                                                              // TODO: You should modify this string to be something appropriate
                                                              // such as the name of your company or organization
                                                              SetRegistryKey(_T("Local AppWizard-Generated Applications"));
                                                           
                                                              CMFCtestDlg dlg;
                                                              m_pMainWnd = &dlg;
                                                              INT_PTR nResponse = dlg.DoModal();
                                                              if (nResponse == IDOK)
                                                              {
                                                                  // TODO: Place code here to handle when the dialog is
                                                                  //  dismissed with OK
                                                              }
                                                              else if (nResponse == IDCANCEL)
                                                              {
                                                                  // TODO: Place code here to handle when the dialog is
                                                                  //  dismissed with Cancel
                                                              }
                                                           
                                                              // Since the dialog has been closed, return FALSE so that we exit the
                                                              //  application, rather than start the application's message pump.
                                                              return FALSE;
                                                          }


                                                        Куда в какое место в нем прописываются хендлы, глобальные переменные, функции, да собственно и потоки?
                                                        Пробую так
                                                        ExpandedWrap disabled
                                                          // MFCtest.cpp : Defines the class behaviors for the application.
                                                          //
                                                           
                                                          #include "stdafx.h"
                                                          #include "MFCtest.h"
                                                          #include "MFCtestDlg.h"
                                                           
                                                          #ifdef _DEBUG
                                                          #define new DEBUG_NEW
                                                          #endif
                                                           
                                                           
                                                          // CMFCtestApp
                                                           
                                                          BEGIN_MESSAGE_MAP(CMFCtestApp, CWinApp)
                                                              ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
                                                          END_MESSAGE_MAP()
                                                           
                                                           
                                                          // CMFCtestApp construction
                                                           
                                                          CMFCtestApp::CMFCtestApp()
                                                          {
                                                              // TODO: add construction code here,
                                                              // Place all significant initialization in InitInstance
                                                          }
                                                           
                                                           
                                                          // The one and only CMFCtestApp object
                                                           
                                                          CMFCtestApp theApp;
                                                           
                                                           
                                                          // CMFCtestApp initialization
                                                           
                                                          BOOL CMFCtestApp::InitInstance()
                                                          {
                                                              // InitCommonControlsEx() is required on Windows XP if an application
                                                              // manifest specifies use of ComCtl32.dll version 6 or later to enable
                                                              // visual styles.  Otherwise, any window creation will fail.
                                                              INITCOMMONCONTROLSEX InitCtrls;
                                                              InitCtrls.dwSize = sizeof(InitCtrls);
                                                              // Set this to include all the common control classes you want to use
                                                              // in your application.
                                                              InitCtrls.dwICC = ICC_WIN95_CLASSES;
                                                              InitCommonControlsEx(&InitCtrls);
                                                           
                                                              CWinApp::InitInstance();
                                                           
                                                              AfxEnableControlContainer();
                                                           
                                                              // Standard initialization
                                                              // If you are not using these features and wish to reduce the size
                                                              // of your final executable, you should remove from the following
                                                              // the specific initialization routines you do not need
                                                              // Change the registry key under which our settings are stored
                                                              // TODO: You should modify this string to be something appropriate
                                                              // such as the name of your company or organization
                                                              SetRegistryKey(_T("Local AppWizard-Generated Applications"));
                                                           
                                                              CMFCtestDlg dlg;
                                                              m_pMainWnd = &dlg;
                                                              INT_PTR nResponse = dlg.DoModal();
                                                              if (nResponse == IDOK)
                                                              {
                                                                  // TODO: Place code here to handle when the dialog is
                                                                  //  dismissed with OK
                                                              }
                                                              else if (nResponse == IDCANCEL)
                                                              {
                                                                  // TODO: Place code here to handle when the dialog is
                                                                  //  dismissed with Cancel
                                                              }
                                                           
                                                              // Since the dialog has been closed, return FALSE so that we exit the
                                                              //  application, rather than start the application's message pump.
                                                              return FALSE;
                                                           
                                                              //---------------------------------------------------------------------------
                                                              // дефайны
                                                           
                                                              //ёмкость буфера приема
                                                              #define BUFSIZE_RD 5000
                                                              //ёмкость буфера передачи
                                                              #define BUFSIZE_WR 128
                                                           
                                                              //---------------------------------------------------------------------------
                                                              // дескрипторы
                                                           
                                                              HANDLE COMport;
                                                              HANDLE writer;
                                                              HANDLE reader;
                                                              HANDLE main;
                                                           
                                                              ///будем использовать для операций чтения (см. поток ReadThread)
                                                              OVERLAPPED overlapped;
                                                              //будем использовать для операций записи (см. поток WriteThread)
                                                              OVERLAPPED overlappedwr;
                                                           
                                                              //---------------------------------------------------------------------------
                                                              // глобальные переменные
                                                           
                                                              // строка определения com порта
                                                          //  String com_port;
                                                           
                                                              // флаг приема
                                                              bool FlComRead;
                                                              // флаг цикла в потоке приема
                                                              bool flag;
                                                           
                                                              bool FlBeg;
                                                           
                                                              //приёмный и передающий буферы
                                                              unsigned char bufrd[BUFSIZE_RD], bufwr[BUFSIZE_WR];
                                                              // контрольная сумма пакета передачи
                                                              unsigned char TxBufCrc;
                                                              unsigned char PrCanal;
                                                              unsigned char PrSect;
                                                           
                                                              // счетчик приемов
                                                              unsigned int counterRX;
                                                              unsigned int counterTX;
                                                              unsigned int counterRP;
                                                              unsigned int Dist;
                                                              unsigned int Distm;
                                                           
                                                              // скорость бод
                                                              unsigned long BaudR;
                                                           
                                                              //---------------------------------------------------------------------------
                                                              // функции
                                                           
                                                              //---------------------------------------------------------------------------
                                                           
                                                              // задержка
                                                              void wait (int wt)
                                                              {
                                                                while (wt--);
                                                              }
                                                           
                                                              //---------------------------------------------------------------------------
                                                              // Принятые байты в HEX
                                                           
                                                              void hexdumpstrRead ( char src[], size_t size)
                                                              {
                                                          //    Form1->Memo2->Clear();
                                                                static const char hex[] = "0123456789abcdef";
                                                                char *result = (char *)malloc((size > 0)? size*3: 1),
                                                                  *p = result;
                                                           
                                                                if (result) {
                                                                  while (size-- > 0) {
                                                                    *p++ = hex[(*src >> 4) & 0x0f];
                                                                    *p++ = hex[*src++ & 0x0f];
                                                                    *p++ = ' ';
                                                                  }
                                                                  p[(p > result)? -1: 0] = 0;
                                                                }
                                                          //    Form1->Memo2->Lines->Add(result);
                                                              }
                                                              //---------------------------------------------------------------------------
                                                              // Переданные байты в HEX
                                                           
                                                              void hexdumpstrWrite ( char src[], size_t size)
                                                              {
                                                          //    Form1->Memo1->Clear();
                                                                static const char hex[] = "0123456789abcdef";
                                                                char *result = (char *)malloc((size > 0)? size*3: 1),
                                                                  *p = result;
                                                           
                                                                if (result) {
                                                                  while (size-- > 0) {
                                                                    *p++ = hex[(*src >> 4) & 0x0f];
                                                                    *p++ = hex[*src++ & 0x0f];
                                                                    *p++ = ' ';
                                                                  }
                                                                  p[(p > result)? -1: 0] = 0;
                                                                }
                                                          //    Form1->Memo1->Lines->Add(result);
                                                              }


                                                        }
                                                        Ошибки типа
                                                        ExpandedWrap disabled
                                                          Error   1   error C2601: 'wait' : local function definitions are illegal
                                                          Цитата Acvarif @
                                                          Ошибки типа

                                                          Так тебе компилятор прямым текстом сообщает об ошибке :-?

                                                          Добавлено
                                                          Кстати сама функция -- это фигня какая-то. Я уж молчу про то, что без volatile компилятор вправе вообще твой while потереть.
                                                            Цитата Acvarif @
                                                            Я не врубаюсь как код с WINAPI прописать в Wisual Studio. Какой вид проекта для этого открыть MFC, WindovsForm, или...?

                                                            Есть три вида Win32-проект, MFC-проект и WinForms-проект. Последний лучше писать на С#.
                                                            Создаешь MFC-проект, самое простое, по типу С++Builder, это диалоговое приложение. Потом кидаешь контролы на форму, и всязываешь с обработчиками :D
                                                            почти как С++Builder там VCL, тут MFC.

                                                            Цитата Acvarif @
                                                            Если начинать проект MFC то куда и чего прописывать
                                                            Напнример в Builder все прописывается в одном едиственном модуле c расширением .cpp

                                                            в случае создания диалогового приложения, изначально можно все запихать в файл срр, где находиться определение главного окна приложения.
                                                            Как создать обработчик в студии, да все просто выбираешь конрол и дабл клик на нем студия сама создаст :D

                                                            Добавлено
                                                            если еще не понял то открывай учебник по MFC и Visual Studio и читай там все описано.
                                                            Сообщение отредактировано: Cfon -
                                                              Спасибо. Полегчало. Visual Studio слишком насыщен разными подходами. С наскоку растерялся. MFC подойдет.
                                                                Потихоньку врубаюсь. Глубоко понять MFC - это еще не скоро. Создал пустой проект с названием MFCtest. В результате имеются 2 файла типа CMFCtest.cpp MFCtestDlg.cpp
                                                                Пока пытаюсь тупо перенести код из Builder6 в файл типа CMFCtest.cpp .Глобальные переменные и функции разместил сразу после
                                                                ExpandedWrap disabled
                                                                  #include "stdafx.h"
                                                                  #include "MFCtest.h"
                                                                  #include "MFCtestDlg.h"
                                                                   
                                                                  #ifdef _DEBUG
                                                                  #define new DEBUG_NEW
                                                                  #endif
                                                                Прокатило. Дальше пытаюсь понять где находится аналог билдеровского создателя формы
                                                                ExpandedWrap disabled
                                                                  void __fastcall TForm1::FormCreate(TObject *Sender)
                                                                чтобы поместить туда функцию создания потока типа
                                                                ExpandedWrap disabled
                                                                  reader = CreateThread( NULL, 0,ReadThread, NULL, CREATE_SUSPENDED, NULL);

                                                                Хотя читал, что MFC требует такого создателя потока reader = AfxBeginThread(ReadThread, NULL, THREAD_PRIORITY_IDLE);
                                                                И тем не менее подскажите please куда необходимо разместить функцию создания потока?
                                                                Вариант размещения создателя потока так
                                                                ExpandedWrap disabled
                                                                  ...
                                                                  // CMFCtestApp
                                                                   
                                                                  BEGIN_MESSAGE_MAP(CMFCtestApp, CWinApp)
                                                                      ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
                                                                  END_MESSAGE_MAP()
                                                                   
                                                                   
                                                                  // CMFCtestApp construction
                                                                   
                                                                  CMFCtestApp::CMFCtestApp()
                                                                  {
                                                                      // TODO: add construction code here,
                                                                      // Place all significant initialization in InitInstance
                                                                      // скорость бод по умолчанию
                                                                      BaudR =  CBR_115200;
                                                                      //reader = CreateThread( NULL, 0, ReadThread, NULL, CREATE_SUSPENDED, NULL);
                                                                      reader = AfxBeginThread(ReadThread, NULL, THREAD_PRIORITY_IDLE);
                                                                      ::Sleep(10);
                                                                   
                                                                  }
                                                                   
                                                                   
                                                                  // The one and only CMFCtestApp object
                                                                   
                                                                  CMFCtestApp theApp;
                                                                   
                                                                   
                                                                  // CMFCtestApp initialization
                                                                   
                                                                  BOOL CMFCtestApp::InitInstance()
                                                                  {
                                                                      // InitCommonControlsEx() is required on Windows XP if an application
                                                                      // manifest specifies use of ComCtl32.dll version 6 or later to enable
                                                                      // visual styles.  Otherwise, any window creation will fail.
                                                                      INITCOMMONCONTROLSEX InitCtrls;
                                                                      InitCtrls.dwSize = sizeof(InitCtrls);
                                                                      // Set this to include all the common control classes you want to use
                                                                      // in your application.
                                                                      InitCtrls.dwICC = ICC_WIN95_CLASSES;
                                                                      InitCommonControlsEx(&InitCtrls);
                                                                   
                                                                  ...

                                                                выдает ошибку
                                                                ExpandedWrap disabled
                                                                  Error   1   error C2665: 'AfxBeginThread' : none of the 2 overloads could convert all the argument types
                                                                Сообщение отредактировано: Acvarif -
                                                                  Цитата Acvarif @
                                                                  Дальше пытаюсь понять где находится аналог билдеровского создателя формы
                                                                  ExpandedWrap disabled
                                                                    void __fastcall TForm1::FormCreate(TObject *Sender)
                                                                  чтобы поместить туда функцию создания потока типа
                                                                  ExpandedWrap disabled
                                                                    reader = CreateThread( NULL, 0,ReadThread, NULL, CREATE_SUSPENDED, NULL);

                                                                  в файл MFCtestDlg.cpp можно в конструктор или вирт функцию OnInitilize

                                                                  Добавлено
                                                                  Цитата Acvarif @
                                                                  Хотя читал, что MFC требует такого создателя потока reader = AfxBeginThread(ReadThread, NULL, THREAD_PRIORITY_IDLE);

                                                                  код который создал мастер студии вообще не трогай, чтобы там что то менять надо хорошо разбираться в MFC :D
                                                                  Сообщение отредактировано: Cfon -
                                                                    Код не трогаю. Перенес глобальные переменные и функции из CMFCtest.cpp в MFCtestDlg.cpp
                                                                    Создание потока разместил после коммента // TODO: Add extra initialization here
                                                                    ExpandedWrap disabled
                                                                      BOOL CMFCtestDlg::OnInitDialog()
                                                                      {
                                                                          CDialog::OnInitDialog();
                                                                       
                                                                          // Add "About..." menu item to system menu.
                                                                       
                                                                          // IDM_ABOUTBOX must be in the system command range.
                                                                          ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
                                                                          ASSERT(IDM_ABOUTBOX < 0xF000);
                                                                       
                                                                          CMenu* pSysMenu = GetSystemMenu(FALSE);
                                                                          if (pSysMenu != NULL)
                                                                          {
                                                                              CString strAboutMenu;
                                                                              strAboutMenu.LoadString(IDS_ABOUTBOX);
                                                                              if (!strAboutMenu.IsEmpty())
                                                                              {
                                                                                  pSysMenu->AppendMenu(MF_SEPARATOR);
                                                                                  pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                                                                              }
                                                                          }
                                                                       
                                                                          // Set the icon for this dialog.  The framework does this automatically
                                                                          //  when the application's main window is not a dialog
                                                                          SetIcon(m_hIcon, TRUE);         // Set big icon
                                                                          SetIcon(m_hIcon, FALSE);        // Set small icon
                                                                       
                                                                          // TODO: Add extra initialization here
                                                                       
                                                                          reader = AfxBeginThread(ReadThread, NULL, THREAD_PRIORITY_IDLE);
                                                                       
                                                                          return TRUE;  // return TRUE  unless you set the focus to a control
                                                                      }

                                                                    Опять ошибка
                                                                    ExpandedWrap disabled
                                                                      Error   1   error C2665: 'AfxBeginThread' : none of the 2 overloads could convert all the argument types

                                                                    Если не сложно, покажите пожалуйста в коде как сделать конструктор для ReadThread, чтобы правильно разместить его вызов в CMFCtestDlg::OnInitDialog().
                                                                      зачем AfxCreateThread? юзай CreateThread ты же её ранее вызывал.

                                                                      функция AfxBeginThread возвращет указатель на CWndThread:
                                                                      ExpandedWrap disabled
                                                                        CWndThread* pThread = AfxBeginThread(ReadThread,GetSafeHwnd(),THREAD_PRIORITY_IDLE);

                                                                      у тебя reader это HANDLE а не указатель.

                                                                      ReaderThread должен объявлен так: UINT ReaderThread(LPVOID);
                                                                      Сообщение отредактировано: Cfon -
                                                                        Спасибо.
                                                                        Поток вроде запустился, и даже COMport = CreateFile... сработал.
                                                                        Интересно есть-ли в MFC аналог билдеровского
                                                                        ExpandedWrap disabled
                                                                          Form1->Memo2->Lines->Add(stroka);

                                                                        которое работает непосредственно в функции потока чтения COM?
                                                                        Сообщение отредактировано: Acvarif -
                                                                          Цитата Acvarif @
                                                                          Интересно есть-ли в MFC аналог билдеровского
                                                                          ExpandedWrap disabled
                                                                            Form1->Memo2->Lines->Add(stroka);

                                                                          конечно есть :D
                                                                          насколько я понял Memo2 это текстовый контрол, в MFC это контрол Edit.
                                                                            Да. Нашел. Все же MFC тяжелый для пнимания. Совершенно не врубаюсь как повторить простейший билдеровский ввод текста из ComboBox1 типа
                                                                            ExpandedWrap disabled
                                                                              Form1->ComboBox1->Text.c_str()

                                                                            Как это выглядит для MFC?
                                                                              Цитата Acvarif @
                                                                              Да. Нашел. Все же MFC тяжелый для пнимания. Совершенно не врубаюсь как повторить простейший билдеровский ввод текста из ComboBox1 типа
                                                                              ExpandedWrap disabled
                                                                                Form1->ComboBox1->Text.c_str()

                                                                              Как это выглядит для MFC?

                                                                              есть несколько вариантов самый простой:
                                                                              ExpandedWrap disabled
                                                                                SetDlgItemText(IDC_EDIT, _T("Привет мир!!!"));

                                                                              IDC_EDIT это идентификатор эдита

                                                                              или так
                                                                              ExpandedWrap disabled
                                                                                CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO);
                                                                                pCombo->InsertString(-1, _T("Текст"));
                                                                              Сообщение отредактировано: Cfon -
                                                                                Спасибо. Функция SetDlgItemText рабтает. Наверняка для вывода данных в оно Edit Control тоже пойдет.
                                                                                Очевидно я неверно задал вопрос. Имелось ввиду обратное - из окна ввода (или списка ComboBox) перенести текст, напрмер в переменную-строку типа CString com_port
                                                                                ...
                                                                                Спасибо. Понял. Работает.
                                                                                Сообщение отредактировано: Acvarif -
                                                                                  получить текст можно с помощью GetDlgItemText.
                                                                                    Цитата Acvarif @
                                                                                    Потихоньку врубаюсь. Глубоко понять MFC - это еще не скоро.

                                                                                    Это довольно старая библиотека.
                                                                                    А это значит, что можно найти немало книг и статей.
                                                                                    Интересная статья
                                                                                    Хороший сайт
                                                                                      Спасибо. Тоже работает. Попытаюсь этой функцией перенести текст типа "COM1" в переменную CString com_pot, а затем в функцию
                                                                                      ExpandedWrap disabled
                                                                                        COMport = CreateFile(com_port,GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                                                                                      которая в свою очередь находится в функции с установками порта
                                                                                      ExpandedWrap disabled
                                                                                        oid Com_Setting()
                                                                                        {
                                                                                          COMMTIMEOUTS timeouts;
                                                                                         
                                                                                        //  com_port += ComboBox1->Text;
                                                                                        //  COMport = CreateFile(L"COM1",GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                                                                                            COMport = CreateFile(com_port,GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
                                                                                         
                                                                                          if(COMport==INVALID_HANDLE_VALUE)
                                                                                          {
                                                                                              if(GetLastError()==ERROR_FILE_NOT_FOUND)
                                                                                              {
                                                                                                  MessageBox(NULL,(LPCWSTR)L"serial port does not exist.",(LPCWSTR)L"",MB_OK);
                                                                                              }
                                                                                            MessageBox(NULL,(LPCWSTR)L"serial port error",(LPCWSTR)L"", MB_OK);
                                                                                          }
                                                                                         
                                                                                          DCB dcbSerialParams = {0};
                                                                                          dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
                                                                                          if (!GetCommState(COMport, &dcbSerialParams))
                                                                                          {
                                                                                              MessageBox(NULL,(LPCWSTR)L"getting state error\n",(LPCWSTR)L"",MB_OK);
                                                                                          }
                                                                                          dcbSerialParams.BaudRate=BaudR;
                                                                                          dcbSerialParams.ByteSize=8;
                                                                                          dcbSerialParams.StopBits=ONESTOPBIT;
                                                                                          dcbSerialParams.Parity=NOPARITY;
                                                                                          if(!SetCommState(COMport, &dcbSerialParams))
                                                                                          {
                                                                                              MessageBox(NULL,(LPCWSTR)L"error setting serial port state\n",(LPCWSTR)L"",MB_OK);
                                                                                          }
                                                                                         
                                                                                          // Установка таймаутов.
                                                                                          timeouts.ReadIntervalTimeout = 10;        // таймаут между двумя символами
                                                                                          timeouts.ReadTotalTimeoutMultiplier = 0;  // общий таймаут операции чтения
                                                                                          timeouts.ReadTotalTimeoutConstant = 0;    // константа для общего таймаута операции чтения
                                                                                          timeouts.WriteTotalTimeoutMultiplier = 0; // общий таймаут операции записи
                                                                                          timeouts.WriteTotalTimeoutConstant = 0;   // константа для общего таймаута операции записи
                                                                                         
                                                                                          // Загрузить структуру таймаутов в порт.
                                                                                          if(!SetCommTimeouts(COMport, &timeouts))
                                                                                          {
                                                                                            // Если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния.
                                                                                            MessageBox(NULL,(LPCWSTR)L"Не удалось установить тайм-ауты\n",(LPCWSTR)L"",MB_OK);
                                                                                            return;
                                                                                          }
                                                                                         
                                                                                          // Установить размеры очередей приёма и передачи
                                                                                          SetupComm(COMport,2000,2000);
                                                                                          // Очистка буферов порта
                                                                                          PurgeComm(COMport,PURGE_RXCLEAR);
                                                                                          // очистить строку имени порта
                                                                                        //  com_port = "";
                                                                                        }
                                                                                        ну получилось? :)
                                                                                          Получается. Для проверки делаю так: По клику Button1 формирую строку типа "COM1" переношу ее в IDC_COMBO1 затем из IDC_COMBO1 извлекаюь строку в переменную str и потом вызываю функцию установок и открытия COM порта, где переменная str попадает в
                                                                                          ExpandedWrap disabled
                                                                                            COMport = CreateFile(str, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);.

                                                                                          ExpandedWrap disabled
                                                                                            void CMFCtestDlg::OnBnClickedButton1()
                                                                                            {
                                                                                             
                                                                                              CString strText(_T("COM1"));
                                                                                              SetDlgItemText(IDC_COMBO1, strText);
                                                                                             
                                                                                                CString str;
                                                                                              GetDlgItemText(IDC_COMBO1, str);
                                                                                             
                                                                                                // установки порта
                                                                                              Com_Setting(str);
                                                                                              // активировать поток чтения данных в порт
                                                                                              ResumeThread(reader);
                                                                                             
                                                                                            }

                                                                                          Порт открывается. Поток вроде запускаетс. Пока не врубаюсь как составить список в ComboBox1 типа ("COM1" "COM2" "COM3" ..)
                                                                                          Сообщение отредактировано: Acvarif -
                                                                                            Цитата Acvarif @
                                                                                            Пока не врубаюсь как составить список в ComboBox1 типа ("COM1" "COM2" "COM3" ..)

                                                                                            а что сложного?
                                                                                            ExpandedWrap disabled
                                                                                              CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBOID);
                                                                                              pCombo->AddString("COM1");
                                                                                              pCombo->AddString("COM2");
                                                                                              pCombo->AddString("COM3");
                                                                                              Спасибо. Сработало. Интересно работает ComboBox При каждом нажатии на стрелку выбора вниз - собственно это вызов функции
                                                                                              // выбор COM порта
                                                                                              ExpandedWrap disabled
                                                                                                void CMFCtestDlg::OnCbnDropdownCombo1()
                                                                                                {
                                                                                                    CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO1);
                                                                                                    pCombo->AddString(L"COM1");
                                                                                                    pCombo->AddString(L"COM2");
                                                                                                    pCombo->AddString(L"COM3");
                                                                                                }

                                                                                              в окне выбора появляется повторение типа
                                                                                              Прикреплённая картинка
                                                                                              Прикреплённая картинка

                                                                                              А.. врубился. Это нужно делать при запуске формы. CMFCtestDlg::OnCbnDropdownCombo1() не нужна.
                                                                                              Сообщение отредактировано: Acvarif -
                                                                                                Цитата Acvarif @
                                                                                                А.. врубился. Это нужно делать при запуске формы. CMFCtestDlg::OnCbnDropdownCombo1() не нужна.

                                                                                                в OnInitDialog :)

                                                                                                еще если это список не меняется то можно в ресурсах его прописать в свойство Data: COM1;COM2;COM3
                                                                                                  Очередной затык. Окно Edit Control.
                                                                                                  Имеется функция void ReadPrinting(DWORD btr) которая вызывается непосредственно в функции-потоке чтения.
                                                                                                  Функция принимает данные о количестве прочитанных байт (DWORD btr) COM портом и тупо выводит данные из глобального буфера bufrd в окно Memo в HEX виде.
                                                                                                  Выглядит это так
                                                                                                  ExpandedWrap disabled
                                                                                                      for(UINT32 i=0; i<btr ; i++)
                                                                                                      {
                                                                                                        stroka = stroka + IntToHex(bufrd[i], 2) + ' ';
                                                                                                      }
                                                                                                      Form1->Memo2->Lines->Add(stroka);

                                                                                                  Подскажите пожалуйста как это можно повторить в MFC - вывести данные в окно Edit Control.
                                                                                                  Для теста пробовал несколько типичных вариантов , например типа
                                                                                                  ExpandedWrap disabled
                                                                                                    SetWindowText(IDC_EDIT1, "Text");

                                                                                                  Неработает. Ошибка
                                                                                                  ExpandedWrap disabled
                                                                                                    Error 1 'SetWindowTextW' : cannot convert parameter 1 from 'int' to 'HWND'
                                                                                                    www.ya.ru, ищем "CEdit MFC" -> находим описание:
                                                                                                    CEdit
                                                                                                    Цитата

                                                                                                    ..
                                                                                                    CEdit наследует значительные возможности из CWnd.
                                                                                                    Для установки и извлечения текста из объекта CEdit, используйте функции-члены
                                                                                                    SetWindowText и GetWindowText
                                                                                                    ...
                                                                                                      Такая конструкция работает
                                                                                                      ExpandedWrap disabled
                                                                                                            CWnd* pWnd = GetDlgItem(IDC_EDIT1);
                                                                                                            pWnd->SetWindowText(_T("Gerald Samper"));

                                                                                                      Но только если вызывается в OnInitDialog или в любом обработчике (кнопки или т. п)
                                                                                                      Если поместить это в любую внешнюю функцию то возникает ошибка
                                                                                                      ExpandedWrap disabled
                                                                                                        Error   1   error C2660: 'GetDlgItem' : function does not take 1 arguments

                                                                                                      В чем хитрость?
                                                                                                      В билдре там просто добавляется Form1->...
                                                                                                      В MFC как?
                                                                                                      Похоже элемент IDC_EDIT1 или вся функция GetDlgItem(IDC_EDIT1), если можно так выразиться, не попадает во внешнюю функцию.
                                                                                                      Сообщение отредактировано: Acvarif -
                                                                                                        Цитата Acvarif @
                                                                                                        В чем хитрость?
                                                                                                        В билдре там просто добавляется Form1->...
                                                                                                        В MFC как?
                                                                                                        Похоже элемент IDC_EDIT1 или вся функция GetDlgItem(IDC_EDIT1), если можно так выразиться, не попадает во внешнюю функцию.

                                                                                                        при создании потока в качестве параметра lParam передается дескриптор на главное окно:
                                                                                                        ExpandedWrap disabled
                                                                                                          DWORD WINAPI WorkThread(LPVOID lParam)
                                                                                                          {
                                                                                                              CWnd* pWnd = CWnd::FromHandle((HWND)lParam);
                                                                                                              CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                              pEdit->SetWindowText(_T("Hello from thread!"));
                                                                                                              return 0;
                                                                                                          }

                                                                                                        также в MFC есть указатель на главное окно сохраненое в члене m_pMainWnd класса CWinApp: AfxGetApp()->m_pMainWnd.
                                                                                                        судя по всему Form1 это тоже указатель на главное окно? :D
                                                                                                        Сообщение отредактировано: Cfon -
                                                                                                          Спасибо. Пнятно. Для проверки поместил код в функцию-поток чтения в то место где собственно производится загрузка принятого байта в буфер bufrd
                                                                                                          ExpandedWrap disabled
                                                                                                                      if(btr)
                                                                                                                      {
                                                                                                                        // прочитать байты из порта в буфер программы
                                                                                                                        ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                                                                                                        // увеличиваем счётчик байтов
                                                                                                                        counterRX+=btr;
                                                                                                                        // вывод данных на экран
                                                                                                                        CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                    CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                    pEdit->SetWindowText(_T("Hello from thread!"));
                                                                                                                      }

                                                                                                          Один раз в секунду на COM прт приходит пакет данных. Явно btr становится не 0 - вызывается код
                                                                                                          ExpandedWrap disabled
                                                                                                            CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                    CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                    pEdit->SetWindowText(_T("Hello from thread!"));

                                                                                                          Просходит странная ошибка, вернее исключение, которое указывает на файл winocc.cpp
                                                                                                          Прикреплённая картинка
                                                                                                          Прикреплённая картинка

                                                                                                          Что-бы это мгло быть. Ведь в общем ничего особо не делается. Просто попытка вывести в окно Edit Control коротий текст. Может это связано с тем, что на порт приходит порядка 800 байт и по сути каждый раз в нем должно отображаться "Hello from thread!" (800 раз) Чего-то не помещается? Сделал Auto scrol true. Не помогло...
                                                                                                          Уменьшил количество байт до 24. То же самое, в отладчике застревает на строке
                                                                                                          ExpandedWrap disabled
                                                                                                            CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                          Сообщение отредактировано: Acvarif -
                                                                                                            Цитата Acvarif @
                                                                                                            Просходит странная ошибка, вернее исключение, которое указывает на файл winocc.cpp
                                                                                                            Что-бы это мгло быть.

                                                                                                            обращение к несуществующему объекту или попросту по нулевому указателю :D
                                                                                                            ты дескриптор окна-владельца передаешь при создании потока?

                                                                                                            Цитата Acvarif @
                                                                                                            То же самое, в отладчике застревает на строке
                                                                                                            ExpandedWrap disabled
                                                                                                              CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);

                                                                                                            невалидный указатель pWnd.
                                                                                                            Сообщение отредактировано: Cfon -
                                                                                                              Функция создания потока
                                                                                                              ExpandedWrap disabled
                                                                                                                reader = CreateThread( NULL, 0,ReadThread, NULL, CREATE_SUSPENDED, NULL);

                                                                                                              Только имя потоковой функции ReadThread. Дескриптор нет. Как это выглядит правильно?
                                                                                                                Цитата Acvarif @
                                                                                                                В чем хитрость?
                                                                                                                В билдре там просто добавляется Form1->...
                                                                                                                В MFC как?
                                                                                                                Похоже элемент IDC_EDIT1 или вся функция GetDlgItem(IDC_EDIT1), если можно так выразиться, не попадает во внешнюю функцию.

                                                                                                                По всей вероятности, в том, один из методов CWnd имеет имя "GetDlgItem".
                                                                                                                Которое совпадает с именем WINDOWS-API функции "GetDlgItem".
                                                                                                                Они имеют разное число параметров.
                                                                                                                Когда функция с таким именем вызывается внутри класса, используется
                                                                                                                функция класса. Снаружи класса вызывается API-функция, которая имеет
                                                                                                                другой прототип. Поэтому появляется сообщение об ошибке.
                                                                                                                  Цитата Acvarif @
                                                                                                                  Функция создания потока
                                                                                                                  ExpandedWrap disabled
                                                                                                                    reader = CreateThread( NULL, 0,ReadThread, NULL, CREATE_SUSPENDED, NULL);

                                                                                                                  Только имя потоковой функции ReadThread. Дескриптор нет. Как это выглядит правильно?

                                                                                                                  4 параметр есть указатель на данные для рабочего потока, передаём в него дескриптор главного окна через GetSafeHwnd():
                                                                                                                  ExpandedWrap disabled
                                                                                                                    reader = CreateThread( NULL, 0,ReadThread, GetSafeHwnd(), CREATE_SUSPENDED, NULL);
                                                                                                                    Спасибо. Работает. Информация в окне Edit Contol отображается нормально, причем с обновлением.
                                                                                                                    Хотя Micosoft пишет про четвертый параметр optional
                                                                                                                    ExpandedWrap disabled
                                                                                                                      lpParameter [in, optional]
                                                                                                                          A pointer to a variable to be passed to the thread.

                                                                                                                    Дааа. В MFC все достаточно жестко..
                                                                                                                      Цитата Acvarif @
                                                                                                                      Дааа. В MFC все достаточно жестко..

                                                                                                                      а мне MFC по кайфу :D
                                                                                                                        Надеюсь на MFC удастся повторить билдеровсую прогу с потоками на API. Во всяком случае прием уже точно работает.
                                                                                                                        Данные COM порта накапливаются в глобальном буфере bufrd
                                                                                                                        ExpandedWrap disabled
                                                                                                                          ReadFile(COMport, bufrd, btr, &temp, &overlapped);

                                                                                                                        Далее их нужно отобразить в окне Edit Contol в HEX виде.
                                                                                                                        В билдере это просто преобразовывалось функцией + пробелы между байтами
                                                                                                                        ExpandedWrap disabled
                                                                                                                            // Перенос буфера в строку.
                                                                                                                            for(UINT32 i=0; i<btr ; i++)
                                                                                                                            {
                                                                                                                              stroka = stroka + IntToHex(bufrd[i], 2) + ' ';
                                                                                                                            }

                                                                                                                        затем строка выводилась в окно Memo
                                                                                                                        Сейчас выводится в окно Edit Control
                                                                                                                        Как в MFC можно повторить это:
                                                                                                                        ExpandedWrap disabled
                                                                                                                          stroka = stroka + IntToHex(bufrd[i], 2) + ' ';
                                                                                                                        Сообщение отредактировано: Acvarif -
                                                                                                                          Цитата Acvarif @
                                                                                                                          Как в MFC можно повторить это:
                                                                                                                          ExpandedWrap disabled
                                                                                                                            stroka = stroka + IntToHex(bufrd[i], 2) + ' ';

                                                                                                                          ExpandedWrap disabled
                                                                                                                            CString s;
                                                                                                                            s.Format("%X", bufrd[i]);
                                                                                                                            Спасибо. Работает. Сделал так:
                                                                                                                            ExpandedWrap disabled
                                                                                                                                  for (int i = 0; i < btr; i++)
                                                                                                                                  {
                                                                                                                                      temp_str.Format(_T(" %X"), bufrd[i]);
                                                                                                                                      stroka = stroka + temp_str + ' ';
                                                                                                                                  }
                                                                                                                               
                                                                                                                                  CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                                  CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                                  pEdit->SetWindowText(stroka);

                                                                                                                            Выводит данные так
                                                                                                                            Прикреплённая картинка
                                                                                                                            Прикреплённая картинка

                                                                                                                            В билдере так
                                                                                                                            Прикреплённая картинка
                                                                                                                            Прикреплённая картинка

                                                                                                                            В MFC некоторые нюансы
                                                                                                                            - не прописывает один 0 в HEX числе
                                                                                                                            - очевидно из-за построчного обновления пропускаются первые несколько данных
                                                                                                                            Как можно устранить эти нюансы?
                                                                                                                            Сообщение отредактировано: Acvarif -
                                                                                                                              Цитата Acvarif @
                                                                                                                              В MFC некоторые нюансы
                                                                                                                              - не прописывает один 0 в HEX числе

                                                                                                                              Это ни к MFC, ни к Билдеру отношения не имеет.
                                                                                                                              Это форматный вывод в "С".
                                                                                                                              Попробуй так:
                                                                                                                              ExpandedWrap disabled
                                                                                                                                temp_str.Format(_T(" %02X"), bufrd[i]);

                                                                                                                              Или даже так:
                                                                                                                              ExpandedWrap disabled
                                                                                                                                TCHAR buf[128]; _sntprintf_s(buf,ARRAYSIZE(buf),_TRUNCATE,_T(" %02X"),bufrd[i]);

                                                                                                                              Почитай про printf/sprintf.
                                                                                                                              тут, например
                                                                                                                                Да. Зарапортовался с форматированием. Спасибо.
                                                                                                                                В билдере было так
                                                                                                                                ExpandedWrap disabled
                                                                                                                                  stroka = stroka + IntToHex(bufrd[i], 2) + ' ';

                                                                                                                                Все же остался один непонятный нюанс - Похоже каждая новая строка записывается на место старой. Все выводится в одну едиственную строку. Как с этим бороться?
                                                                                                                                Сообщение отредактировано: Acvarif -
                                                                                                                                  Цитата Acvarif @
                                                                                                                                  Все же остался один непонятный нюанс - Похоже каждая новая строка записывается на место старой. Все выводится в одну едиственную строку. Как с этим бороться?

                                                                                                                                  Эти "технологии" я тебе уже показывал:
                                                                                                                                  www.ya.ru, ищем "CEdit MFC" и находим описание
                                                                                                                                  тут.
                                                                                                                                  Цитата

                                                                                                                                  ...
                                                                                                                                  CEdit наследует значительные возможности из CWnd. Для установки и извлечения текста из объекта CEdit, используйте функции-члены SetWindowText и GetWindowTextCWnd, устанавливающие или получающие все содержимое элемента управления "Поле ввода", даже если многострочный элемент управления. Линии многополосном текста в элементе управления разделены последовательности символов "\r\n". Кроме того, если элемент управления "Поле ввода" многополосн, получение и установка часть текста элемента управления путем вызова функции-члены GetLine, SetSel, GetSel и ReplaceSelCEdit.
                                                                                                                                  ...
                                                                                                                                  Сообщение отредактировано: ЫукпШ -
                                                                                                                                    Эта ссылка у меня открыта. Но всеравно не врубаюсь.
                                                                                                                                    Цитата
                                                                                                                                    Линии многополосном текста в элементе управления разделены последовательности символов "\r\n".

                                                                                                                                    Это что означает? На практике получается, что каждый новый вызов кода
                                                                                                                                    ExpandedWrap disabled
                                                                                                                                          // Перенос буфера в строку.
                                                                                                                                          for (DWORD i = 0; i < btr; i++)
                                                                                                                                          {
                                                                                                                                              temp_str.Format(_T(" %02X"), bufrd[i]);
                                                                                                                                              stroka = stroka + temp_str + ' ';
                                                                                                                                          }
                                                                                                                                       
                                                                                                                                          CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                                          CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                                          pEdit->SetWindowText(stroka);

                                                                                                                                    стирает предыдущую строку и печатает новую на ее место.
                                                                                                                                    Что в коде нужно добавить, отнять, изменить, чтобы просто каждый новый его вызов печатал строку с новой строки?
                                                                                                                                      Цитата Acvarif @
                                                                                                                                      Эта ссылка у меня открыта. Но всеравно не врубаюсь.

                                                                                                                                      я не использую MFC.
                                                                                                                                      Но судя по этому описанию - как-то так:
                                                                                                                                      ExpandedWrap disabled
                                                                                                                                        // ...
                                                                                                                                        for (DWORD i = 0; i < btr; i++)
                                                                                                                                        {
                                                                                                                                         temp_str.Format(_T(" %02X"), bufrd[i]);
                                                                                                                                         stroka = stroka + temp_str + ' ';
                                                                                                                                        }
                                                                                                                                        stroka += "\r\n";
                                                                                                                                        //...
                                                                                                                                        Спасибо. Мысль неплохая.
                                                                                                                                        Но все оказалось круто закручено. Итак понятно, что каждое выполнение кода
                                                                                                                                        ExpandedWrap disabled
                                                                                                                                          CString stroka, temp_str;
                                                                                                                                          // Перенос буфера в строку.
                                                                                                                                              for (DWORD i = 0; i < btr; i++)
                                                                                                                                              {
                                                                                                                                                  temp_str.Format(_T(" %02X"), bufrd[i]);
                                                                                                                                                  stroka = stroka + temp_str + ' ';
                                                                                                                                              }
                                                                                                                                           
                                                                                                                                              CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                                              CEdit* pEdit = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                                              pEdit->SetWindowText(stroka);

                                                                                                                                        приводит к новому выводу строки в Edit Control
                                                                                                                                        Это значит, что если непрерывный пакет данных в буфере приемника COM будет появляться с некоторыми временными разрывами то это уже будет не непрерывный пакет данных и функция ReadPrinting(btr, lpParam); вывода данных в Edit Control (так какраз и выполняется вышеприведенный код) будет вызываться многократно. Все заложено в функции потока чтения
                                                                                                                                        //---------------------------------------------------------------------------
                                                                                                                                        ExpandedWrap disabled
                                                                                                                                          // Поток чтения
                                                                                                                                           
                                                                                                                                          DWORD WINAPI ReadThread( LPVOID lpParam )
                                                                                                                                          {
                                                                                                                                            // структура текущего состояния порта,
                                                                                                                                            // используется для определения количества принятых в порт байт
                                                                                                                                            COMSTAT comstat;
                                                                                                                                            // переменная temp используется в качестве заглушки
                                                                                                                                            DWORD btr, temp, mask, signal;
                                                                                                                                            // создать сигнальный объект-событие для асинхронных операций
                                                                                                                                            overlapped.hEvent = CreateEvent(NULL, true, true, NULL);
                                                                                                                                            // установить маску на срабатывание по событию приёма байта в порт
                                                                                                                                            SetCommMask(COMport, EV_RXCHAR);
                                                                                                                                            // пока поток не будет прерван, выполняем цикл
                                                                                                                                            while(1)
                                                                                                                                            {
                                                                                                                                              //ожидать события приёма байта (это и есть перекрываемая операция)
                                                                                                                                              WaitCommEvent(COMport, &mask, &overlapped);
                                                                                                                                              //приостановить поток до прихода байта
                                                                                                                                              signal = WaitForSingleObject(overlapped.hEvent, INFINITE);
                                                                                                                                              //если событие прихода байта произошло
                                                                                                                                              if(signal == WAIT_OBJECT_0)
                                                                                                                                              {
                                                                                                                                                //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
                                                                                                                                                if(GetOverlappedResult(COMport, &overlapped, &temp, true))
                                                                                                                                                {
                                                                                                                                                  //если произошло именно событие прихода байта
                                                                                                                                                  if((mask & EV_RXCHAR)!=0)
                                                                                                                                                  {
                                                                                                                                              ::Sleep(100);
                                                                                                                                                    // нужно заполнить структуру COMSTAT
                                                                                                                                                    ClearCommError(COMport, &temp, &comstat);
                                                                                                                                                    // и получить из неё количество принятых байтов
                                                                                                                                                    btr = comstat.cbInQue;
                                                                                                                                                    // если действительно есть байты для чтения
                                                                                                                                                    if(btr)
                                                                                                                                                    {
                                                                                                                                                      // прочитать байты из порта в буфер программы
                                                                                                                                                      ReadFile(COMport, bufrd, btr, &temp, &overlapped);
                                                                                                                                                      // вызываем функцию для вывода данных на экран
                                                                                                                                                      ReadPrinting(btr, lpParam);
                                                                                                                                                    }
                                                                                                                                                  }
                                                                                                                                                }
                                                                                                                                              }
                                                                                                                                            Sleep(1);
                                                                                                                                            }
                                                                                                                                            return 1;
                                                                                                                                          }

                                                                                                                                        Собственно, чтобы избежать повторений нужно или задержать вход в if(btr) или CString stroka, temp_str; сделать глобальными, чтобы очищать их как-то, когда в Edit Control отобразится нужное количество принятых данных.
                                                                                                                                        Пока помогла не вдаваться в такие дебри небольшая задержка
                                                                                                                                        ExpandedWrap disabled
                                                                                                                                          if((mask & EV_RXCHAR)!=0)
                                                                                                                                                  {
                                                                                                                                              ::Sleep(100);

                                                                                                                                        Теперь вход в
                                                                                                                                        ExpandedWrap disabled
                                                                                                                                          if(btr)
                                                                                                                                                    {

                                                                                                                                        осуществляется один раз при непрерывном пакете данных на COM (порядка 800 байт с перидом в 1 сек) Функция ReadPrinting(btr, lpParam); выполняется один раз - окно Edit Control отображает корректно весь пакет принятых данных.
                                                                                                                                        Если у кого есть по этому поводу еще какие мысли, буду признателен.
                                                                                                                                        Сообщение отредактировано: Acvarif -
                                                                                                                                          Цитата Acvarif @
                                                                                                                                          Но все оказалось круто закручено. Итак понятно, что каждое выполнение кода
                                                                                                                                          ...
                                                                                                                                          приводит к новому выводу строки в Edit Control

                                                                                                                                          Вообще непонятно, что ты хочешь.
                                                                                                                                          Если ты получаешь не строки, а байт - так и выводи байты.
                                                                                                                                          Поставь непрерывный счётчик байт, равный размеру строки.
                                                                                                                                          По достижению максимального значения - сбрасывай счётчик и добавляй
                                                                                                                                          два байта в Эдит '\r','\n'.
                                                                                                                                          Дополнительные операции со строками только время тратят.
                                                                                                                                            Цитата Acvarif @
                                                                                                                                            Все же остался один непонятный нюанс - Похоже каждая новая строка записывается на место старой. Все выводится в одну едиственную строку. Как с этим бороться?

                                                                                                                                            Цитата Acvarif @
                                                                                                                                            Что в коде нужно добавить, отнять, изменить, чтобы просто каждый новый его вызов печатал строку с новой строки?

                                                                                                                                            Вместо CEdit::SetWindowText:
                                                                                                                                            ExpandedWrap disabled
                                                                                                                                              int len = pEdit->GetWindowTextLength();
                                                                                                                                              pEdit->SetSel(len, len);    
                                                                                                                                              pEdit->ReplaceSel(_T("\r\nНовая строка"));

                                                                                                                                            :D
                                                                                                                                            Сообщение отредактировано: Cfon -
                                                                                                                                              Цитата
                                                                                                                                              Вообще непонятно, что ты хочешь.
                                                                                                                                              Если ты получаешь не строки, а байт - так и выводи байты.
                                                                                                                                              Поставь непрерывный счётчик байт, равный размеру строки.
                                                                                                                                              По достижению максимального значения - сбрасывай счётчик и добавляй
                                                                                                                                              два байта в Эдит '\r','\n'.

                                                                                                                                              Может я сразу не написал почему используется асинхронный прием - прием по событию прихода каждого байта.
                                                                                                                                              Все дело в том, что пакеты данных переменной длины (от 800 до 4000 байт). Каждый новый пакет - другая длина. Поэтому подсчитать что-то конкретное невозможно. Вот и выкручиваюсь... Кроме того, ответная передача пакета управления (128 байт информации) должна быть по времени (разрыв не более 10 мс)жестко привязана к концу приема. Конец к счастью можно определить по конкретным конечным символам в пакете прима.
                                                                                                                                              Пока в MFC прием работает не хуже чем в Builder.
                                                                                                                                              В Builder имеется возможность выводить строку в Label, Panel типа
                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);

                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                sprintf(Buffer,"Дистанция: %d м", Distm);
                                                                                                                                                      Form1->Label16->Caption = Buffer;

                                                                                                                                              В MFC имеется Text Control. Можно-ли в Text Control выводить текст примерно как Panel3->Caption =.. или Label16->Caption = ..?
                                                                                                                                              Сообщение отредактировано: Acvarif -
                                                                                                                                                Цитата Acvarif @
                                                                                                                                                В Builder имеется возможность выводить строку в Label, Panel типа
                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                  Form1->Panel3->Caption = "Всего принято байт: " + IntToStr(counterRX);

                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                  sprintf(Buffer,"Дистанция: %d м", Distm);
                                                                                                                                                        Form1->Label16->Caption = Buffer;

                                                                                                                                                В MFC имеется Text Control. Можно-ли в Text Control выводить текст примерно как Panel3->Caption =.. или Label16->Caption = ..?

                                                                                                                                                Естестно :D
                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                  CStatic* pText = (CStatic*)GetDlgItem(IDC_STATIC1);
                                                                                                                                                  pText->SetWindowText(_T("Hello"));

                                                                                                                                                также имеется возможность определить объект соотвествующего класса и обращаться непросредствено через него:
                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                  class CDialog1 : public CDialog
                                                                                                                                                  {
                                                                                                                                                  public:
                                                                                                                                                      CStatic label1;
                                                                                                                                                  };
                                                                                                                                                   
                                                                                                                                                  void CDialog1::DoDataExchange(CDataExchange* pDX)
                                                                                                                                                  {
                                                                                                                                                      CDialog::DoDataExchange(pDX);
                                                                                                                                                      DDX_Control(pDX, IDC_STATIC1, label1);
                                                                                                                                                  }
                                                                                                                                                   
                                                                                                                                                  BOOL CDialog1::OnInitDialog()
                                                                                                                                                  {
                                                                                                                                                      CDialog::OnInitDialog();
                                                                                                                                                      label1.SetWindowText(_T("Hello"));
                                                                                                                                                  }
                                                                                                                                                Сообщение отредактировано: Cfon -
                                                                                                                                                  Цитата Acvarif @
                                                                                                                                                  Может я сразу не написал почему используется асинхронный прием - прием по событию прихода каждого байта.
                                                                                                                                                  Все дело в том, что пакеты данных переменной длины (от 800 до 4000 байт). Каждый новый пакет - другая длина.

                                                                                                                                                  1. Или выводи по-байтно.
                                                                                                                                                  2. Или принимай по-одному, но накапливай в выводной буфер число байт, равное длине строки
                                                                                                                                                  твоего "виртуального" дисплея, и выводи.
                                                                                                                                                  3. Или читай из буфера порта операцией чтения максимальный размер (допустим 4000 байт).
                                                                                                                                                  С указанным тайм-аутом по приходу байт.
                                                                                                                                                  Почитай подробнее про тайм-ауты и выбери подходящий.
                                                                                                                                                  Будешь принимать или по максимальному количеству или по тайм-ауту
                                                                                                                                                  некоторое количество байт. Получишь - выводи.
                                                                                                                                                  ---
                                                                                                                                                  Все 3 способа будут работать - 100%.
                                                                                                                                                  Единственное требование - чтобы твой компьютер мог в принципе справится
                                                                                                                                                  с таким потоком байт.
                                                                                                                                                    Цитата
                                                                                                                                                    Или принимай по-одному..
                                                                                                                                                    Так и делаю. Вроде работает.

                                                                                                                                                    Цитата
                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                         CStatic* pText = (CStatic*)GetDlgItem(IDC_STATIC1);
                                                                                                                                                          pText->SetWindowText(_T("Hello"));

                                                                                                                                                    Понятно. Спасибо. По ходу разобрался со сменой фонта в IDC_EDIT1
                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                      // фонт для IDC_EDIT1
                                                                                                                                                          CFont *font = new CFont;
                                                                                                                                                          CEdit* pEditFont = (CEdit*)pWnd->GetDlgItem(IDC_EDIT1);
                                                                                                                                                          font->CreateFont (
                                                                                                                                                          20,                        // nHeight
                                                                                                                                                          0,                         // nWidth
                                                                                                                                                          0,                         // nEscapement
                                                                                                                                                          0,                         // nOrientation
                                                                                                                                                          FW_NORMAL,                 // nWeight
                                                                                                                                                          FALSE,                     // bItalic
                                                                                                                                                          FALSE,                     // bUnderline
                                                                                                                                                          0,                         // cStrikeOut
                                                                                                                                                          ANSI_CHARSET,              // nCharSet
                                                                                                                                                          OUT_DEFAULT_PRECIS,        // nOutPrecision
                                                                                                                                                          CLIP_DEFAULT_PRECIS,       // nClipPrecision
                                                                                                                                                          DEFAULT_QUALITY,           // nQuality
                                                                                                                                                          DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
                                                                                                                                                          L"Arial");                 // lpszFacename
                                                                                                                                                          pEditFont->SetFont(font);

                                                                                                                                                    Похоже удастся весь процесс приема передачи сделать в одном потоке.


                                                                                                                                                    В билдере элемент выбора типа ComboBox работает непосредственно с выбранным в окне текстом.
                                                                                                                                                    В MFC код выбора работает с опозданием на строку.
                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                      void CMFCtestDlg::OnCbnSelchangeCombo3()
                                                                                                                                                      {
                                                                                                                                                          CString strCombo3;
                                                                                                                                                          GetDlgItemText(IDC_COMBO3, strCombo3);
                                                                                                                                                       
                                                                                                                                                        if(strCombo3 == "откл.")
                                                                                                                                                        {
                                                                                                                                                          bufwr[1] &= ~(1 << 0);
                                                                                                                                                          bufwr[1] &= ~(1 << 1);
                                                                                                                                                        }
                                                                                                                                                        else if(strCombo3 == "мин.")
                                                                                                                                                        {
                                                                                                                                                          bufwr[1] |= (1 << 0);
                                                                                                                                                          bufwr[1] &= ~(1 << 1);
                                                                                                                                                        }
                                                                                                                                                        else if(strCombo3 == "макс.")
                                                                                                                                                        {
                                                                                                                                                          bufwr[1] &= ~(1 << 0);
                                                                                                                                                          bufwr[1] |= (1 << 1);
                                                                                                                                                        }
                                                                                                                                                      }

                                                                                                                                                    При выборе в bufwr[1] записываются данные соответствующие предыдущему состоянию окна IDC_COMBO3
                                                                                                                                                    Как сделать так чтобы срабатывало то, что выбрано в настоящий момент?
                                                                                                                                                    Сообщение отредактировано: Acvarif -
                                                                                                                                                      Цитата Acvarif @
                                                                                                                                                      В билдере элемент выбора типа ComboBox работает непосредственно с выбранным в окне текстом.
                                                                                                                                                      В MFC код выбора работает с опозданием на строку.

                                                                                                                                                      Как сделать так чтобы срабатывало то, что выбрано в настоящий момент?

                                                                                                                                                      дело в том что событие OnCbnSelchangeCombo3 срабатывает до замены текста в редакторе комбо, поэтому вызов GetDlgItemText считывает предыдущее значение. Выход считывать текущее значение на основе выбранного пункта из списка значений комбо с помощью GetLBText.
                                                                                                                                                      ExpandedWrap disabled
                                                                                                                                                        void CMFCtestDlg::OnCbnSelchangeCombo3()
                                                                                                                                                        {
                                                                                                                                                            CString strCombo3;
                                                                                                                                                            CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO3);
                                                                                                                                                            pCombo->GetLBText(pCombo->GetCurSel(),strCombo3);
                                                                                                                                                         
                                                                                                                                                        }
                                                                                                                                                      Сообщение отредактировано: Cfon -
                                                                                                                                                        Спасибо. Работает.
                                                                                                                                                        В билдере имеется функция закрытия формы типа
                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                          void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

                                                                                                                                                        В ней обычно останавливаются потоки, закрывается порт и т. п.
                                                                                                                                                        Как можно сделать то-же в MFC?
                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                          В билдере имеется функция закрытия формы типа
                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                            void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

                                                                                                                                                          В ней обычно останавливаются потоки, закрывается порт и т. п.
                                                                                                                                                          Как можно сделать то-же в MFC?

                                                                                                                                                          обработать сообщение WM_CLOSE :)
                                                                                                                                                          пс. на самом деле MFC является всего лишь классовой надстройкой над Win32 API, поэтому все то что делалось в чистом Win32 API применимо и к MFC.
                                                                                                                                                            Возник один неприятный момент. При переносе проекта из одного компа на другой (с домашнего на рабочий) при компиляции возникает ошибка:
                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                              Error   1   fatal error C1853: 'Debug\MFCtest.pch' precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa) d:\mydesignsxp\visualstprj\mfctest\mfctest\mfctestdlg.cpp   1   MFCtest

                                                                                                                                                            В чем фишка? На компах разные версии компиляторов? (не уверен, что ставил Студию из одного и того-же источника) Как с этим бороться?
                                                                                                                                                            Проект пока еще не такой большой. Можно начать заново. Но потом наверняка ситуация повторится если на выходные буду переносить проект обранто с рабочего компа на домашний.
                                                                                                                                                              Цитата Acvarif @
                                                                                                                                                              Возник один неприятный момент. При переносе проекта из одного компа на другой (с домашнего на рабочий) при компиляции возникает ошибка:
                                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                                Error   1   fatal error C1853: 'Debug\MFCtest.pch' precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa) d:\mydesignsxp\visualstprj\mfctest\mfctest\mfctestdlg.cpp   1   MFCtest

                                                                                                                                                              В чем фишка? На компах разные версии компиляторов? (не уверен, что ставил Студию из одного и того-же источника) Как с этим бороться?
                                                                                                                                                              Проект пока еще не такой большой. Можно начать заново. Но потом наверняка ситуация повторится если на выходные буду переносить проект обранто с рабочего компа на домашний.

                                                                                                                                                              просто удали этот файл и снова откомпилируй :)
                                                                                                                                                              вообще когда переносишь проект куда-нибудь, то делай перед этим очистку командой Build -> Clean, это действие удаляет почти все вспомогательные файлы, в том числе файл предкомпилированого заголовка pch, а также объектные и exe файлы, которые слову сказать много весят, особенно pch.
                                                                                                                                                              Сообщение отредактировано: Cfon -
                                                                                                                                                                Спасибо. Заработал прием и передача в одном потоке. Вывод данных на Edit Control в норме.
                                                                                                                                                                Имеются еще некоторые нюансы. Например Static Text почему-то не имеет своего ID. Любой Static Text (1,2 или 9 )имеет ID IDC_STATIC вместо IDC_STATIC1, IDC_STATIC2, ..IDC_STATIC9
                                                                                                                                                                Прикреплённая картинка
                                                                                                                                                                Прикреплённая картинка

                                                                                                                                                                Попытка обратиться к нему по
                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                  CStatic* pText = (CStatic*)GetDlgItem(IDC_STATIC9);
                                                                                                                                                                      pText->SetWindowText(_T("Hello"));
                                                                                                                                                                ID типа IDC_STATIC9 приводит к ошибке
                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                  Error   4   error C2065: 'IDC_STATIC9' : undeclared identifier
                                                                                                                                                                Это ошибка самой среды Visual Studio2008+MFC?
                                                                                                                                                                Сообщение отредактировано: Acvarif -
                                                                                                                                                                  Цитата Acvarif @
                                                                                                                                                                  Спасибо. Заработал прием и передача в одном потоке. Вывод данных на Edit Control в норме.
                                                                                                                                                                  Имеются еще некоторые нюансы. Например Static Text почему-то не имеет своего ID. Любой Static Text (1,2 или 9 )имеет ID IDC_STATIC вместо IDC_STATIC1, IDC_STATIC2, ..IDC_STATIC9

                                                                                                                                                                  Это ошибка самой среды Visual Studio2008+MFC?

                                                                                                                                                                  по умолчанию статик контролы имеют одинаковый ID: IDC_STATIC, поэтому чтобы обратиться к ним надо просто указать ID отличный от IDC_STATIC, например IDC_STATIC1 :)
                                                                                                                                                                    Спасибо. Static работает. В билдере имеется компонент тпа CSpinEdit
                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                       void __fastcall TForm1::CSpinEdit6Change(TObject *Sender)
                                                                                                                                                                      {
                                                                                                                                                                        bufwr[124] = (CSpinEdit6->Value - 1) | ((Dist >> 1) & 0x80);
                                                                                                                                                                       
                                                                                                                                                                      }

                                                                                                                                                                    Работает он по событию клика на верхнюю или нижнюю стрелку прокрутки
                                                                                                                                                                    Прикреплённая картинка
                                                                                                                                                                    Прикреплённая картинка

                                                                                                                                                                    Значение в нем меняется на 1 вверх или вниз в пределах заранее установленных границ в свойствах компонента (например min 1 max 120).
                                                                                                                                                                    Как в MFC можно создать подобный компонент. Имеется в наличии Spin Control но без окна Edit. Очевидно придется компоновать Spin Control + Edit Control?
                                                                                                                                                                      Цитата Acvarif @
                                                                                                                                                                      Как в MFC можно создать подобный компонент. Имеется в наличии Spin Control но без окна Edit. Очевидно придется компоновать Spin Control + Edit Control?

                                                                                                                                                                      :yes: надо у спин конторла установить свойства Auto Buddy = True и Set Buddy Integer = True, клики на кнопках обрабатываются через сообщение WM_VSCROLL, которое отлавливается окном диалога. Начальную инициализацию "спина" можно сделать в OnInitDialog.
                                                                                                                                                                      Edit Control надо ставить рядом слева от Spin контрола согласно Tab-порядку.

                                                                                                                                                                      ExpandedWrap disabled
                                                                                                                                                                        BOOL CMyDialog::OnInitDialog()
                                                                                                                                                                        {  
                                                                                                                                                                            CDialog::OnInitDialog();
                                                                                                                                                                         
                                                                                                                                                                            static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_SPIN1))->SetRange(0,100);              
                                                                                                                                                                         
                                                                                                                                                                            return TRUE;  
                                                                                                                                                                        }
                                                                                                                                                                         
                                                                                                                                                                        void CMyDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
                                                                                                                                                                        {      
                                                                                                                                                                            if (pScrollBar->GetDlgCtrlID() == IDC_SPIN1)
                                                                                                                                                                            {
                                                                                                                                                                                //int spinValue = reinterpret_cast<CSpinButtonCtrl*>(pScrollBar)->GetPos32();
                                                                                                                                                                                bufwr[124] = (nPos - 1) | ((Dist >> 1) & 0x80);
                                                                                                                                                                            }
                                                                                                                                                                         
                                                                                                                                                                            CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
                                                                                                                                                                        }
                                                                                                                                                                      Сообщение отредактировано: Cfon -
                                                                                                                                                                        Спасибо. С установкой Spin+Edit Control разобрался. Все нормально ставится. С обработкой клика не получается.
                                                                                                                                                                        В функции BOOL CMFCtestDlg::OnInitDialog() добавил строку
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_SPIN2))->SetRange(0,100);
                                                                                                                                                                        (работаю с IDC_SPIN2)
                                                                                                                                                                        Появилась ошибка
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          Error   5   error C2061: syntax error : identifier 'CSpinButtonCtr1'
                                                                                                                                                                        Хотя потом создал переменную типа m_spin2Value и сделал запись
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          m_spin2Value.SetRange(1,120);
                                                                                                                                                                        что установило диапазон изменения для Spin
                                                                                                                                                                        Подключение в основной файл MFCtestDld.cpp функции
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          void CMFCtestDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
                                                                                                                                                                          {      
                                                                                                                                                                              if (pScrollBar->GetDlgCtrlID() == IDC_SPIN2)
                                                                                                                                                                              {
                                                                                                                                                                                  bufwr[124] = (nPos - 1) | ((Dist >> 1) & 0x80);
                                                                                                                                                                              }
                                                                                                                                                                           
                                                                                                                                                                              CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
                                                                                                                                                                          }

                                                                                                                                                                        вызывает ошибку
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          Error   6   error C2509: 'OnVScroll' : member function not declared in 'CMFCtestDlg'

                                                                                                                                                                        Тут не совсем врубился. У Edit Control есть событие типа
                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                          void CMFCtestDlg::OnEnVscrollEdit5()

                                                                                                                                                                        Что представляет из себя функция void CMFCtestDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)?
                                                                                                                                                                        Я ее просто прописал в файл MFCtestDld.cpp.
                                                                                                                                                                        Сообщение отредактировано: Acvarif -
                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                          У Edit Control есть событие типа
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            void CMFCtestDlg::OnEnVscrollEdit5()

                                                                                                                                                                          Edit Control в данном случае можно вообще игнорировать все делает Spin control.

                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            Error   6   error C2509: 'OnVScroll' : member function not declared in 'CMFCtestDlg'

                                                                                                                                                                          Что представляет из себя функция void ::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)?

                                                                                                                                                                          это обработчик сообщения WM_VSCROLL.

                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                          Я ее просто прописал в файл MFCtestDld.cpp.

                                                                                                                                                                          можно вручную, но тогда надо сделать по шагам следующее:
                                                                                                                                                                          1) объявить в классе диалога функцию-обработчик void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
                                                                                                                                                                          2) определить ее;
                                                                                                                                                                          3) ну и обязательно разместить след код в таблице сообщений:
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            BEGIN_MESSAGE_MAP(CMFCtestDlg, CDialog)
                                                                                                                                                                            ...
                                                                                                                                                                                ON_WM_VSCROLL()
                                                                                                                                                                            ...
                                                                                                                                                                            END_MESSAGE_MAP()

                                                                                                                                                                          но проще воспользоваться соотвествующим мастером ClassView, который добавит весь этот код сам. Для этого открываешь окно ClassView, выбираешь класс CMFCtestDlg, далее в окне Properties -> Messages и там находишь сообщение WM_VSCROLL :D

                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                          В функции BOOL CMFCtestDlg::OnInitDialog() добавил строку
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_SPIN2))->SetRange(0,100);
                                                                                                                                                                          (работаю с IDC_SPIN2)
                                                                                                                                                                          Появилась ошибка
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            Error   5   error C2061: syntax error : identifier 'CSpinButtonCtr1'

                                                                                                                                                                          хз должно работать. CSpinButtonCtrl это обертка для виндового spin контрола.

                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                          Хотя потом создал переменную типа m_spin2Value и сделал запись
                                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                                            m_spin2Value.SetRange(1,120);
                                                                                                                                                                          что установило диапазон изменения для Spin

                                                                                                                                                                          а как создал? код приведи.
                                                                                                                                                                          Сообщение отредактировано: Cfon -
                                                                                                                                                                            Спасибо. Разобрался. Добавил через Properties -> Messages
                                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                                              void CMFCtestDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
                                                                                                                                                                              {
                                                                                                                                                                                  // TODO: Add your message handler code here and/or call default
                                                                                                                                                                                if (pScrollBar->GetDlgCtrlID() == IDC_SPIN2)
                                                                                                                                                                                {
                                                                                                                                                                                    //int spinValue = reinterpret_cast<CSpinButtonCtrl*>(pScrollBar)->GetPos32();
                                                                                                                                                                                    bufwr[124] = (nPos - 1) | ((Dist >> 1) & 0x80);
                                                                                                                                                                                }
                                                                                                                                                                               
                                                                                                                                                                                  CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
                                                                                                                                                                              }

                                                                                                                                                                            Работает.
                                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                                              static_cast<CSpinButtonCtrl*>(GetDlgItem(IDC_SPIN2))->SetRange(0,100);

                                                                                                                                                                            Это тоже работает. Очевидно была механ. ошибка. В CSpinButtonCtrl вместо l(L) стояла 1(1)
                                                                                                                                                                            Переменную
                                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                                              m_spin2Value
                                                                                                                                                                            создавал через Add Variable для Spin
                                                                                                                                                                            Прикреплённая картинка
                                                                                                                                                                            Прикреплённая картинка
                                                                                                                                                                            Сообщение отредактировано: Acvarif -
                                                                                                                                                                              Цитата Acvarif @
                                                                                                                                                                              Переменную
                                                                                                                                                                              ExpandedWrap disabled
                                                                                                                                                                                m_spin2Value
                                                                                                                                                                              создавал через Add Variable для Spin

                                                                                                                                                                              правильно, но в данном случае она не нужна :)
                                                                                                                                                                              это в C++Builder их лепят без надобности, тут все по взрослому :D
                                                                                                                                                                                Цитата Acvarif @
                                                                                                                                                                                Переменную
                                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                                  m_spin2Value
                                                                                                                                                                                создавал через Add Variable для Spin
                                                                                                                                                                                Прикреплённая картинка
                                                                                                                                                                                Прикреплённая картинка

                                                                                                                                                                                "Частота бод" - звучит, как фраза из далёкого прошлого.
                                                                                                                                                                                Сечас пишут "bps" - bits per second - бит в секунду.
                                                                                                                                                                                ---
                                                                                                                                                                                я вот чего хотел узнать - в среде Борланд Билдера надо-ли
                                                                                                                                                                                каким-то образом указывать ID контрола ?
                                                                                                                                                                                (Того-же статика, как у тебя в этом проекте, например)
                                                                                                                                                                                Или там всё автомотизировано ?
                                                                                                                                                                                  В Билдере все автоматизировано.
                                                                                                                                                                                  Например клик по ComboBox5 (который уже выставлен на форму) - появляется функция в которой производятся операции с переменными, локальными или глобальными
                                                                                                                                                                                  ExpandedWrap disabled
                                                                                                                                                                                    void __fastcall TForm1::ComboBox5Click(TObject *Sender)
                                                                                                                                                                                    {
                                                                                                                                                                                      if(ComboBox5->Text == "15-25м")
                                                                                                                                                                                      {
                                                                                                                                                                                        bufwr[1] &= ~(1 << 5);
                                                                                                                                                                                      }
                                                                                                                                                                                      else if(ComboBox5->Text == "25-40м")
                                                                                                                                                                                      {
                                                                                                                                                                                        bufwr[1] |= (1 << 5);
                                                                                                                                                                                      }
                                                                                                                                                                                    }

                                                                                                                                                                                  В качестве ID просто названия типа ComboBox5.
                                                                                                                                                                                  По поводу Контрола. Что имеется ввиду? Если например CSpinEdit который повторяет Edit Control+Spin Control MFC то тоже все просто. Например изменение данных в окне на 1
                                                                                                                                                                                  ExpandedWrap disabled
                                                                                                                                                                                    void __fastcall TForm1::CSpinEdit2Change(TObject *Sender)
                                                                                                                                                                                    {
                                                                                                                                                                                      PrCanal = CSpinEdit2->Value;
                                                                                                                                                                                     
                                                                                                                                                                                    }

                                                                                                                                                                                  Value - готовая переменная, одинаковая почти для всех Контролов, в которой данные меняются при клике вверх или вниз.
                                                                                                                                                                                  PrCanal - пользовательская переменная
                                                                                                                                                                                  А Статика вообще проще-простого
                                                                                                                                                                                  Например вывод данных в Статик под названием Label16 (это то же что и ID)из пременной Distm
                                                                                                                                                                                  ExpandedWrap disabled
                                                                                                                                                                                    sprintf(Buffer,"Дистанция: %d м", Distm);
                                                                                                                                                                                          Form1->Label16->Caption = Buffer;

                                                                                                                                                                                  Buffer - обычно char Buffer[20] - достаточно для небольшого текста
                                                                                                                                                                                  Сообщение отредактировано: Acvarif -
                                                                                                                                                                                    Цитата Acvarif @
                                                                                                                                                                                    А Статика вообще проще-простого

                                                                                                                                                                                    Если в MFC "этого" нет, ты можешь сам "это" сделать.
                                                                                                                                                                                    Прямо сейчас, и даже ещё лучше..
                                                                                                                                                                                    Наследуемся от класса... эээ.. который "статик".
                                                                                                                                                                                    Который, наверное, CStatic.
                                                                                                                                                                                    Перегружаем метод SetWindowText.
                                                                                                                                                                                    Или пишем метод SetWindowTextEx.
                                                                                                                                                                                    И пишем что-то вроде:
                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                      // ---------------------------------------------------------------------------------
                                                                                                                                                                                      void WINAPI CStaticEx::SetWindowTextEx(const TCHAR* pFmt,...)
                                                                                                                                                                                      {
                                                                                                                                                                                       if(!pFmt) return;
                                                                                                                                                                                       va_list ap;        //Указатель на список параметров
                                                                                                                                                                                       va_start(ap,pFmt); //Настроились на список параметров
                                                                                                                                                                                       
                                                                                                                                                                                       TCHAR sss[32768];
                                                                                                                                                                                       
                                                                                                                                                                                       size_t sizeBuff  = ARRAYSIZE(sss);
                                                                                                                                                                                       
                                                                                                                                                                                       _vsntprintf_s(sss,sizeBuff,_TRUNCATE,pFmt,ap);
                                                                                                                                                                                       SetWindowText(sss);
                                                                                                                                                                                       
                                                                                                                                                                                       va_end(ap); //Завершаем работу с макрокомандами
                                                                                                                                                                                      }
                                                                                                                                                                                      // ---------------------------------------------------------------------------------


                                                                                                                                                                                    В результате ты сможешь писать:
                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                      CStaticEx xxmm;
                                                                                                                                                                                      //...
                                                                                                                                                                                       xxmm.SetWindowTextEx(_T("Дистанция: %d м"), Distm);
                                                                                                                                                                                      //...


                                                                                                                                                                                    В результате число таких конструкций:
                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                      char Buffer[20]; sprintf(Buffer,"Дистанция: %d м", Distm);
                                                                                                                                                                                      //Buffer - обычно  - достаточно для небольшого текста

                                                                                                                                                                                    резко уменьшится.
                                                                                                                                                                                    Сообщение отредактировано: ЫукпШ -
                                                                                                                                                                                      Может быть. Мне трудно судить. Былдер в свое время был идеальной средой для разработки визуальных приложений. Если в метку типа Label1 (Static Control)нужно поместить текст то без всяких заморочек
                                                                                                                                                                                      ExpandedWrap disabled
                                                                                                                                                                                        Label1->Caption = "текст";
                                                                                                                                                                                      Потом они продались Delphi и все пошло враздрай. До сих пор пользуюсь Builder 6. Это новое Embarcadero - страшно к нему подступиться, такого там наворочали. MFC неплохо придуман. На первый взгляд небольшое неудобство - мало компонентов. Хотя может в большинстве случаев того, что есть, вполне достаточно..
                                                                                                                                                                                        Цитата Acvarif @
                                                                                                                                                                                        Былдер в свое время был идеальной средой для разработки визуальных приложений. Если в метку типа Label1 (Static Control)нужно поместить текст то без всяких заморочек
                                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                                          Label1->Caption = "текст";

                                                                                                                                                                                        MFC код длинее, но не сложнее :D
                                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                                          SetDlgItemText(IDC_STATIC1,"текст");

                                                                                                                                                                                        IDC_STATIC1 - это идентификатор ресурса в файле rc, SetDlgItemText - функция-член класса CWnd. Все просто :)

                                                                                                                                                                                        Цитата Acvarif @
                                                                                                                                                                                        MFC неплохо придуман. На первый взгляд небольшое неудобство - мало компонентов. Хотя может в большинстве случаев того, что есть, вполне достаточно..

                                                                                                                                                                                        их (компонентов) вообще нет, это контролы - классы для управления объектами виндос (окнами) :D
                                                                                                                                                                                        Сообщение отредактировано: Cfon -
                                                                                                                                                                                          Спасибо за помощь.
                                                                                                                                                                                          Билдеровскую прогу удалось повторить на MFC. Все (прием-передача) крутится в одном потоке. Немного причешу и выложу в архиве. Может кому будет полезна.
                                                                                                                                                                                          Далее задачка разобрать по косточкам буфер приема и отобразить на цветной панели цветные прямоугольники. Панель разбита сеткой прямоугольных ячеек. 120 по горизонтали, 500 по вертикали 120Х500. Принимаемые данные грубо говоря это координаты ячеек в сетке которые нужно засвечивать цветом отличным от цвета сетки и цвета пустой ячейки. Пока это задача минимум. Как правильно поступиь? Прикручивать к проекту OpenGl (GLUT и т.п.) или можно обойтись средствами MFC?
                                                                                                                                                                                            И ради этого ты с Билдера ушёл?
                                                                                                                                                                                            Цитата
                                                                                                                                                                                            приклепать сложную графику
                                                                                                                                                                                              Нет. Дальше графика действительно сложная. Сетка это пока начало.
                                                                                                                                                                                                Цитата Acvarif @
                                                                                                                                                                                                Нет. Дальше графика действительно сложная. Сетка это пока начало.

                                                                                                                                                                                                я бы GLUT прикрутил для реально сложной графики :)
                                                                                                                                                                                                  В скрепке архив проекта MFCtest. Прикреплённый файлПрикреплённый файлMFCtest.rar (146,87 Кбайт, скачиваний: 81) Может кому пригодится в качестве примера приема-передачи по COM в асинхронном режиме. Также в архиве есть текстовый файл MFCtest.txt который является тестовой текстовой строкой для известной программы работы с COM портом ComPortTolkit. На ПК должно быть как минимум 2 COM порта соединенных перекрестным кабелем (выход передачи одного на вход приема другого). Один работает на передачу из программы ComPortTolkit. Другой на прием с пом. проги из проекта MFCtest.
                                                                                                                                                                                                  ComPortTolkit передает порядка 850 байт на MFCtest обратно получает ответ 128 байт.
                                                                                                                                                                                                  Если где чего не так не судите строго.
                                                                                                                                                                                                    Цитата Acvarif @
                                                                                                                                                                                                    Прикручивать к проекту OpenGl (GLUT и т.п.) или можно обойтись средствами MFC?

                                                                                                                                                                                                    Скорее всего MFC (т.е. обычного GDI) хватит.
                                                                                                                                                                                                      Все же попробую GLUT. Скачал и раскидал нужные файлы по нужным местам http://rucodes.com/opengl-microsoft-visual-studio-c.html
                                                                                                                                                                                                      Дальше немного растерялся. В проекте имеется глобальный буфер bufrd[] где каждую секунду обновляются данные с COM порта, которые нуно разобрать и отобразить в графическом окне.
                                                                                                                                                                                                      Каким образом создается графическое окно с GLUT? Это должен быть отдельный файл в составе существующего проекта? Какова технология добавления графического окна к уже существующему проекту?
                                                                                                                                                                                                        Цитата Acvarif @
                                                                                                                                                                                                        Все же попробую GLUT.
                                                                                                                                                                                                        ...
                                                                                                                                                                                                        В проекте имеется глобальный буфер bufrd[]...
                                                                                                                                                                                                        Дальше немного растерялся.
                                                                                                                                                                                                        ...
                                                                                                                                                                                                        Какова технология добавления графического окна к уже существующему проекту?

                                                                                                                                                                                                        Упс...
                                                                                                                                                                                                        Получается, что ты даже отдалённо не знаешь, какова
                                                                                                                                                                                                        должна быть структура проекта.
                                                                                                                                                                                                        А выбор уже сделал.. :huh:
                                                                                                                                                                                                        Глобальный буфер с данными в многопоточной программе я бы не посоветовал.
                                                                                                                                                                                                        Это и не нужно ни с какой точки зрения.
                                                                                                                                                                                                          Структуру не представляю. Простейший поиск по сети - приложения GLUT консольные WIN32. Какова должна быть структура MFC GLUT пока смутно представляю. Очевидно должен быть еще один поток. В имеющемся файле ..Dlg или.. не врубаюсь. Чем плох глобальный буфер?
                                                                                                                                                                                                          Сообщение отредактировано: Acvarif -
                                                                                                                                                                                                            Цитата Acvarif @
                                                                                                                                                                                                            Очевидно должен быть еще один поток. В имеющемся файле ..Dlg или.. не врубаюсь. Чем плох глобальный буфер?

                                                                                                                                                                                                            Этим вот и плох.
                                                                                                                                                                                                            Из одного потока буфер заполняется.
                                                                                                                                                                                                            Из другого читается.
                                                                                                                                                                                                            Как будешь синхронизировать эти потоки для доступа к данным ?
                                                                                                                                                                                                              Думаю с помщью флага. Ведь период обмена 1 сек. Буфер заполняется (115200) примерно через 100 мс. Далее установка флага и работа с буфером до конца секунды. Но обычно делаются качели - 2 глобальных буфера которые заполняются попеременно. Пока один заполняется с другим можно работать. в следующую секунду все меняется местами. Ничего особенного.. Не врубаюсь где нужно писать код с GLUT, в каком файле? Где запускать поток, в каком файле? Каким образом в проекте должно появиться графическое окно? Совсем смутно с этим.
                                                                                                                                                                                                              По поводу двух потоков - понял. Спасибо.
                                                                                                                                                                                                              Не в тему.
                                                                                                                                                                                                              С наступающим Новым Годом! Всех благ! Удачи!
                                                                                                                                                                                                              Сообщение отредактировано: Acvarif -
                                                                                                                                                                                                                Цитата Acvarif @
                                                                                                                                                                                                                Но обычно делаются качели - 2 глобальных буфера которые заполняются попеременно. Пока один заполняется с другим можно работать. в следующую секунду все меняется местами. Ничего особенного..

                                                                                                                                                                                                                ..И тут вдруг будет обнаружено, что эта "естественная синхронизация" может,
                                                                                                                                                                                                                хотя и изредко, нарушаться.
                                                                                                                                                                                                                Когда второй буфер уже заполнен и происходит обмен буферами, первый ещё не считан
                                                                                                                                                                                                                и, как раз в этот момент, считывается.
                                                                                                                                                                                                                  Цитата Acvarif @
                                                                                                                                                                                                                  Не врубаюсь где нужно писать код с GLUT, в каком файле? Где запускать поток, в каком файле? Каким образом в проекте должно появиться графическое окно? Совсем смутно с этим.

                                                                                                                                                                                                                  определяешь функцию потока, в которой пишешь код glut, потом вызываешь через AfxBeginThread :)
                                                                                                                                                                                                                  из какого места? например по нажатию кнопки.

                                                                                                                                                                                                                  Добавлено
                                                                                                                                                                                                                  с наступающим Новым годом петуха! :D
                                                                                                                                                                                                                  Сообщение отредактировано: Cfon -
                                                                                                                                                                                                                    Цитата
                                                                                                                                                                                                                    определяешь функцию потока, в которой пишешь код glut, потом вызываешь через AfxBeginThread
                                                                                                                                                                                                                    из какого места? например по нажатию кнопки.
                                                                                                                                                                                                                    с наступающим Новым годом петуха!
                                                                                                                                                                                                                    С Новым Годом! Всех благ!
                                                                                                                                                                                                                    Определил функцию потока рисования и входящие в нее функции
                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                      void display()
                                                                                                                                                                                                                      {
                                                                                                                                                                                                                          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                                                                                                                                                                                                       
                                                                                                                                                                                                                          glPushMatrix();
                                                                                                                                                                                                                          glRotatef(ang, 0.0, 1.0, 0.0);
                                                                                                                                                                                                                          glutSolidTeapot(1.0);
                                                                                                                                                                                                                          glPopMatrix();
                                                                                                                                                                                                                       
                                                                                                                                                                                                                          glutSwapBuffers();
                                                                                                                                                                                                                      }
                                                                                                                                                                                                                       
                                                                                                                                                                                                                      void reshape(int x, int y)
                                                                                                                                                                                                                      {
                                                                                                                                                                                                                          glMatrixMode(GL_PROJECTION);
                                                                                                                                                                                                                          glLoadIdentity();
                                                                                                                                                                                                                          gluPerspective(60, (float)x/(float)y, 0.1, 100);
                                                                                                                                                                                                                          glMatrixMode(GL_MODELVIEW);
                                                                                                                                                                                                                          glLoadIdentity();
                                                                                                                                                                                                                          gluLookAt(0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
                                                                                                                                                                                                                       
                                                                                                                                                                                                                          glEnable(GL_DEPTH_TEST);
                                                                                                                                                                                                                          glEnable(GL_LIGHTING);
                                                                                                                                                                                                                          glEnable(GL_LIGHT0);
                                                                                                                                                                                                                      }
                                                                                                                                                                                                                       
                                                                                                                                                                                                                      void idle()
                                                                                                                                                                                                                      {
                                                                                                                                                                                                                          glutPostRedisplay();
                                                                                                                                                                                                                      }
                                                                                                                                                                                                                       
                                                                                                                                                                                                                      DWORD WINAPI ImageThread(LPVOID lpParam)
                                                                                                                                                                                                                      {
                                                                                                                                                                                                                          glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
                                                                                                                                                                                                                          glutCreateWindow("test");
                                                                                                                                                                                                                       
                                                                                                                                                                                                                          glutDisplayFunc(display);
                                                                                                                                                                                                                          glutReshapeFunc(reshape);
                                                                                                                                                                                                                          glutIdleFunc(idle);
                                                                                                                                                                                                                          glutMainLoop();
                                                                                                                                                                                                                       
                                                                                                                                                                                                                          return 0;
                                                                                                                                                                                                                      }


                                                                                                                                                                                                                    По запуску программы создал поток
                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                          image = CreateThread( NULL, 0, ImageThread, GetSafeHwnd(), CREATE_SUSPENDED, NULL);
                                                                                                                                                                                                                        Sleep(10);

                                                                                                                                                                                                                    По нажатию кнопки поток запускается
                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                      void CMFCtestDlg::OnBnClickedButton4()
                                                                                                                                                                                                                      {
                                                                                                                                                                                                                          // активировать поток рисования
                                                                                                                                                                                                                          ResumeThread(image);
                                                                                                                                                                                                                      }

                                                                                                                                                                                                                    При запуске 'Build' все застревает на функции создания окна
                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                          glutCreateWindow("test");


                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                      Error   1   error LNK2019: unresolved external symbol ___glutCreateWindowWithExit@8 referenced in function _glutCreateWindow_ATEXIT_HACK@4  MFCtestDlg.obj  MFCtest
                                                                                                                                                                                                                      Error   2   fatal error LNK1120: 1 unresolved externals

                                                                                                                                                                                                                    Не врубаюсь, что не определено?
                                                                                                                                                                                                                    Сообщение отредактировано: Acvarif -
                                                                                                                                                                                                                      Фух.. Запустилось. Толком и не понял в чем была проблема. Перезагрузил в системные папки Windows файлы .dll и в папки Lib и др. Visual Studio файлы скачанные из другого источника.
                                                                                                                                                                                                                      Прикреплённая картинка
                                                                                                                                                                                                                      Прикреплённая картинка
                                                                                                                                                                                                                        Цитата Acvarif @
                                                                                                                                                                                                                        Фух.. Запустилось.

                                                                                                                                                                                                                        :good: :victory:
                                                                                                                                                                                                                          По ходу возник актуальный вопрос. Если возникнет необходимость на GLUT нарисовать весь интерфейс с сеткой, кнопками, окнами прокрутки - можно-ли будет управлять кнопками, окнами с помощью мышки и клавиатуры? Или можно-ли встроить интерфейс сделанный в MFC в графическое окно GLUT?
                                                                                                                                                                                                                          Сообщение отредактировано: Acvarif -
                                                                                                                                                                                                                            Цитата Acvarif @
                                                                                                                                                                                                                            Или можно-ли встроить интерфейс сделанный в MFC в графическое окно GLUT?

                                                                                                                                                                                                                            У GLUT есть свой цикл обработки сообщений, как их совместить с MFC циклом хз. Надо лезть в сорсы глут и изучать.
                                                                                                                                                                                                                              Можно-ли поместить окно GLUT в окно Edit Contol MFC? Или просто жестко привязать - разместить на форме MFC.
                                                                                                                                                                                                                                Glut неплохо все рисует.
                                                                                                                                                                                                                                Прикреплённая картинка
                                                                                                                                                                                                                                Прикреплённая картинка

                                                                                                                                                                                                                                Но возникла проблема с прорисовкой движения мети (зеленая полоска на изображении).
                                                                                                                                                                                                                                Оказалось, что функция glutMainLoop() не имеет возврата. Если она вызывается, например, в потоке рисования то на ней все и застревает.
                                                                                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                                                                                  // сетка с меткой
                                                                                                                                                                                                                                  void Display()
                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                                                                                                                                                                                                                    glBegin(GL_LINES);
                                                                                                                                                                                                                                      glColor3f(1.0, 1.0, 1.0);
                                                                                                                                                                                                                                      // по горизонтали
                                                                                                                                                                                                                                    for(int i = -WinWidth/2; i <= WinWidth/2; i += 5)
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                          if(i%100 == 0 || i == 0) glColor3f(0.0, 1.0, 1.0);
                                                                                                                                                                                                                                          else glColor3f(0.5, 0.5, 0.5);
                                                                                                                                                                                                                                          glVertex2f(i, -WinHeight);
                                                                                                                                                                                                                                      glVertex2f(i, WinWidth);
                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                      glColor3f(0.5, 0.5, 0.5);
                                                                                                                                                                                                                                      // по вертикали
                                                                                                                                                                                                                                    for(int i = -WinWidth/2; i <= WinWidth/2; i += 100)
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                          glVertex2f(-WinHeight, i);
                                                                                                                                                                                                                                      glVertex2f(WinHeight, i);
                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                    glEnd();
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                    glColor3f( 0.0, 1.0, 0.0 );          
                                                                                                                                                                                                                                    glPolygonMode( GL_FRONT, GL_FILL );
                                                                                                                                                                                                                                    glBegin( GL_POLYGON );                
                                                                                                                                                                                                                                      glVertex2i( x+0, y+1 );
                                                                                                                                                                                                                                      glVertex2i( x+5, y+1 );  
                                                                                                                                                                                                                                      glVertex2i( x+5, y+0 );  
                                                                                                                                                                                                                                      glVertex2i( x+0, y+0 );  
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                    glEnd();
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                    glFlush();
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                  //---------------------------------------------------------------------------
                                                                                                                                                                                                                                  // Поток рисования
                                                                                                                                                                                                                                  DWORD WINAPI ImageThread(LPVOID lpParam)
                                                                                                                                                                                                                                  {
                                                                                                                                                                                                                                      counterRX = counterRX + 5;
                                                                                                                                                                                                                                      CString str_static10;
                                                                                                                                                                                                                                      //
                                                                                                                                                                                                                                      CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                                                                                                                                      // получить указатель на IDC_STATIC10
                                                                                                                                                                                                                                      CStatic* pText10 = (CStatic*)pWnd->GetDlgItem(IDC_STATIC10);
                                                                                                                                                                                                                                      str_static10.Format(_T("Прием %d"), counterRX);
                                                                                                                                                                                                                                      pText10->SetWindowText(str_static10);
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                      glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
                                                                                                                                                                                                                                      glMatrixMode(GL_PROJECTION);
                                                                                                                                                                                                                                      glLoadIdentity();
                                                                                                                                                                                                                                      glViewport(0, 0, WinWidth, WinHeight);
                                                                                                                                                                                                                                    glutInitWindowSize(WinWidth, WinHeight);
                                                                                                                                                                                                                                    glutCreateWindow("Drawing with GLUT");
                                                                                                                                                                                                                                    glutDisplayFunc(Display);
                                                                                                                                                                                                                                   
                                                                                                                                                                                                                                    glutMainLoop();
                                                                                                                                                                                                                                      Sleep(1);
                                                                                                                                                                                                                                      return 0;
                                                                                                                                                                                                                                  }

                                                                                                                                                                                                                                Для проверки в поток добавил счетчик counterRX с выводом на IDC_STATIC10.
                                                                                                                                                                                                                                После запуска программы появляется рисунок но дальше явно все застревает на glutMainLoop(); поскольку счетчик останавливается на числе 5. При этом поток приема-передачи по COM работает нормально.
                                                                                                                                                                                                                                Получается что в данном случае можно нарисовать только статическую картинку.
                                                                                                                                                                                                                                Понимаю, что вопрос не в тему MFC, но может кто сталкивался с MFC+GLUT и динамическими картинками. Как решить вопрос MFC+GLUT_динамическое?
                                                                                                                                                                                                                                  думаю надо юзать glutIdleFunc и передать ей колбяк функцию:
                                                                                                                                                                                                                                  ExpandedWrap disabled
                                                                                                                                                                                                                                    void MyIdleProc()
                                                                                                                                                                                                                                        /* Код, который меняет переменные, определяющие следующий кадр */ 
                                                                                                                                                                                                                                        .... 
                                                                                                                                                                                                                                    }; 
                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                    void MyDisplayProc()
                                                                                                                                                                                                                                        /* Код OpenGL, который отображает кадр */ 
                                                                                                                                                                                                                                        .... 
                                                                                                                                                                                                                                        /* После отрисовки мы переставляем (заменяем) буфера */ 
                                                                                                                                                                                                                                        glutSwapBuffers(); 
                                                                                                                                                                                                                                    }; 
                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                    void main(int argcp, char **argv)
                                                                                                                                                                                                                                    {
                                                                                                                                                                                                                                        ....
                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                        /* Регистрация вызываемых функций */ 
                                                                                                                                                                                                                                        glutDisplayFunc(MyDisplay);
                                                                                                                                                                                                                                        glutIdleFunc(MyIdle);
                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                        /* Запуск механизма обработки событий */ 
                                                                                                                                                                                                                                        glutMainLoop(); 
                                                                                                                                                                                                                                    }
                                                                                                                                                                                                                                  Сообщение отредактировано: Cfon -
                                                                                                                                                                                                                                    Спасибо. Пробую так. Весь код в файле MFCtestDlg.cpp
                                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                      int x = 0, y = 0;
                                                                                                                                                                                                                                      int counterTr;
                                                                                                                                                                                                                                      ...
                                                                                                                                                                                                                                      void Idle()
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                        /* Код, который меняет переменные, определяющие следующий кадр */
                                                                                                                                                                                                                                        x = x + 5;
                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                    Функция тображающая сетку с меткой в координатах x y
                                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                                      void Display()
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                          /* Код OpenGL, который отображает кадр */
                                                                                                                                                                                                                                          glMatrixMode(GL_PROJECTION);
                                                                                                                                                                                                                                          glLoadIdentity();
                                                                                                                                                                                                                                          glOrtho(-WinWidth/2, WinWidth/2, -WinHeight/2, WinHeight/2, -1.0, 1.0);
                                                                                                                                                                                                                                          // горизонтальные и вертикальные линии сетки
                                                                                                                                                                                                                                          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                                                                                                                                                                                                                        glBegin(GL_LINES);
                                                                                                                                                                                                                                          glColor3f(1.0, 1.0, 1.0);
                                                                                                                                                                                                                                          // по горизонтали
                                                                                                                                                                                                                                        for(int i = -WinWidth/2; i <= WinWidth/2; i += 5)
                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                              if(i%100 == 0 || i == 0) glColor3f(0.0, 1.0, 1.0);
                                                                                                                                                                                                                                              else glColor3f(0.5, 0.5, 0.5);
                                                                                                                                                                                                                                              glVertex2f(i, -WinHeight);
                                                                                                                                                                                                                                          glVertex2f(i, WinWidth);
                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                          glColor3f(0.5, 0.5, 0.5);
                                                                                                                                                                                                                                          // по вертикали
                                                                                                                                                                                                                                        for(int i = -WinWidth/2; i <= WinWidth/2; i += 100)
                                                                                                                                                                                                                                          {
                                                                                                                                                                                                                                              glVertex2f(-WinHeight, i);
                                                                                                                                                                                                                                          glVertex2f(WinHeight, i);
                                                                                                                                                                                                                                        }
                                                                                                                                                                                                                                        glEnd();
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                          // зеленая мета с координатами x, y
                                                                                                                                                                                                                                        glColor3f( 0.0, 1.0, 0.0 );          
                                                                                                                                                                                                                                        glPolygonMode( GL_FRONT, GL_FILL );
                                                                                                                                                                                                                                        glBegin( GL_POLYGON );                
                                                                                                                                                                                                                                        glVertex2i( x+0, y+2 );
                                                                                                                                                                                                                                        glVertex2i( x+5, y+2 );  
                                                                                                                                                                                                                                        glVertex2i( x+5, y+0 );  
                                                                                                                                                                                                                                        glVertex2i( x+0, y+0 );  
                                                                                                                                                                                                                                        glEnd();
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                        glFlush();
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                      /* После отрисовки мы переставляем (заменяем) буфера */  
                                                                                                                                                                                                                                          glutSwapBuffers();  
                                                                                                                                                                                                                                      }


                                                                                                                                                                                                                                    Далее поток рисования
                                                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                                                      DWORD WINAPI ImageThread(LPVOID lpParam)
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                         // контроль работы потока по изменению counterRX
                                                                                                                                                                                                                                          counterTr = counterTr + 5;
                                                                                                                                                                                                                                          CString str_static10;
                                                                                                                                                                                                                                          //
                                                                                                                                                                                                                                          CWnd* pWnd = CWnd::FromHandle((HWND)lpParam);
                                                                                                                                                                                                                                          // получить указатель на IDC_STATIC10
                                                                                                                                                                                                                                          CStatic* pText10 = (CStatic*)pWnd->GetDlgItem(IDC_STATIC10);
                                                                                                                                                                                                                                        //вывести сообщение об этом в строке состояния
                                                                                                                                                                                                                                          str_static10.Format(_T("Прием %d"), counterTr);
                                                                                                                                                                                                                                          pText10->SetWindowText(str_static10);
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                      // выполняется один раз после запуса программы
                                                                                                                                                                                                                                      if(!win)
                                                                                                                                                                                                                                      {
                                                                                                                                                                                                                                        win = 1;
                                                                                                                                                                                                                                          glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
                                                                                                                                                                                                                                          glMatrixMode(GL_PROJECTION);
                                                                                                                                                                                                                                          glLoadIdentity();
                                                                                                                                                                                                                                          glViewport(0, 0, WinWidth, WinHeight);
                                                                                                                                                                                                                                        glutInitWindowSize(WinWidth, WinHeight);
                                                                                                                                                                                                                                        glutCreateWindow("Drawing with GLUT");
                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                        // вызов функций рисования Display и смены координаты x Idle
                                                                                                                                                                                                                                        glutDisplayFunc(Display);
                                                                                                                                                                                                                                        glutIdleFunc(Idle);
                                                                                                                                                                                                                                        glutMainLoop();
                                                                                                                                                                                                                                        Sleep(1);
                                                                                                                                                                                                                                        return 0;
                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                    Все прорисовывается нормально, но застревает на glutMainLoop() Счетчик counterTr останавливается на положении 5. Не врубаюсь, что я сделал не верно?
                                                                                                                                                                                                                                    Сообщение отредактировано: Acvarif -
                                                                                                                                                                                                                                      Спасибо. Работает. Метка начала двигаться. По поводу встраивания окна Glut в MFC http://www.codeguru.com/cpp/cpp/cpp_mfc/tu...trol.htm#page-2
                                                                                                                                                                                                                                        :victory:
                                                                                                                                                                                                                                          Цитата Acvarif @
                                                                                                                                                                                                                                          По поводу встраивания окна Glut в MFC http://www.codeguru.com/cpp/cpp/cpp_mfc/tu...trol.htm#page-2

                                                                                                                                                                                                                                          Хочу внести уточнение, на самом деле GLUT это независимая от платформы библиотека со своей оконной системой, поэтому ее нельзя было встроить в окно MFC или еще куда. А пример по ссылке приводится описание интеграции OpenGL и GLU (это не GLUT) в MFC через механизм Windows GL (WGL)
                                                                                                                                                                                                                                          ;)

                                                                                                                                                                                                                                          На самом деле это даже более правильный способ использования OpenGL с MFC :)
                                                                                                                                                                                                                                          GLUT как правило используется в программировании игр, ну и хорошо подходит для изучения OpenGL.

                                                                                                                                                                                                                                          Сделал пример отрисовки OpenGL в окно MFC (максимально упростил :D):
                                                                                                                                                                                                                                          Прикреплённый файлПрикреплённый файлExample5.rar (67,49 Кбайт, скачиваний: 106)
                                                                                                                                                                                                                                          Сообщение отредактировано: Cfon -
                                                                                                                                                                                                                                            Спасибо за уточнение и пример.
                                                                                                                                                                                                                                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                                                                                                                                            0 пользователей:


                                                                                                                                                                                                                                            Рейтинг@Mail.ru
                                                                                                                                                                                                                                            [ Script execution time: 0,5496 ]   [ 41 queries used ]   [ Generated: 28.04.24, 02:27 GMT ]