Форум программистов, компьютерный форум, киберфорум
C++: WinAPI
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
1

Дочернее окно копируется в не дочернее(хотя не должно)

22.07.2016, 12:16. Просмотров 624. Ответов 10
Метки нет (Все метки)

При нажатии кнопки появляется окно, но вместо того, что бы отрисоваться как надо, в него копируется дочернее окно главного окна. При закрытии появляющегося окна, закрывается и главное(завершается приложение). Использование GetDC приводит к глюкам.
Без GetDC()

Дочернее окно копируется в не дочернее(хотя не должно)


С GetDC()

Дочернее окно копируется в не дочернее(хотя не должно)


В виду сложности проблемы(для меня) привожу почти весь код, с незначительными сокращениями

Добавлено через 5 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#include <windows.h>
#include "com.h"
#define ID_BUTTON_1 3000     //идентификатор кнопки
#define ID_BUTTON_2 3001     //идентификатор кнопки
#define ID_BUTTON_3 3002     //идентификатор кнопки
#define ID_BUTTON_4 3003     //идентификатор кнопки
#define ID_BUTTON_5 3004     //идентификатор кнопки
#define ID_COMBOCOM_0 1000   //идентификатор Combo Box
#define ID_COMBOCOM_1 1001   //идентификатор Combo Box
 
HWND hBtn1;         // хендл  кнопки 1 (Open COM port)
HWND hBtn2;         // хендл  кнопки 2 (New)
HWND hBtn3;         // хендл  кнопки 3 (Send)
HWND hBtn4;         // хендл  кнопки 4 (Choose)
HWND hBtn5;         // хендл  кнопки 5 (Save)
HWND hComboPort;    // хендл  меню  ComboBox портов
HWND hBaudRate;     // хендл  меню  ComboBox скорости
HINSTANCE hInstance;
HINSTANCE trhInstance;
HINSTANCE ctrhInstance;
HBRUSH hbrush;      //создаём объект-кисть
PAINTSTRUCT ps;     //структура рисования
HDC hdc;            //создаём контекст устройства
HDC memdc;          //создаём контекст устройства
 
MSG trmsg;            // Структура для хранения сообщения окна графиков
MSG ctrmsg;           // Структура для хранения сообщения окна создания графиков
 
char ComName[5];        //имя порта (например, "COM1", "COM2" и т.д.)
char FileName[] = "COM.dat";       //имя файла, в который будут записываться принятые данные
unsigned int BaudRate = 0;  //скорость передачи в бодах(9600. 19200. 38400. 57600. 115200)
uint8_t CharData = 0b00000000; //даннные, передаваемые по таймеру
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
 
    HWND hMainWnd;  // Дескриптор будущего главного окна
    char szClassName[] = "MyClass";
    MSG msg;        // Структура для хранения сообщения
    WNDCLASSEX wc;        // Класс окна
// дальше просто создаем главное окно
}
 
#include "trend.h"
 
LRESULT CALLBACK WndProc(HWND hMainWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{
  int SelectedCom=0;
  int SelectedRate=0;
  int maxX=0, maxY=0;        //максимальные координаты по х и по у
  HBITMAP hbit;              //объект изображение окна
  bool TimerEnable = true;   //запускаем таймер и периодически шлем в COM сообщения
  static bool NewWindOpen = false;  //окно настройки закрыто
  LPCTSTR WindowText_1 = "Выберите COM порт";
  LPCTSTR WindowText_2 = "Выберите скорость передачи";
  
    switch (msg) 
    {
        case WM_CREATE:
        {  
          //окно графиков----------------------------------------------------------------------------------------------
          MyRegisterChildClass();
          hTrWnd = CreateWindowEx(WS_EX_CLIENTEDGE, trClassName, "Trends", WS_CHILD|WS_VISIBLE, 170, 10, 810, 440, hMainWnd, NULL, trhInstance, NULL);//|WS_OVERLAPPED
          //окно графиков----------------------------------------------------------------------------------------------
          hdc=GetDC(hMainWnd);                //получаем контекст изображения
          maxX=GetSystemMetrics(SM_CXSCREEN); //узнаём максимальные координаты по х  
          maxY=GetSystemMetrics(SM_CYSCREEN); //узнаём максимальные координаты по у
          //Создаем Combobox ;
          hComboPort=CreateWindow("Combobox",NULL,WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST, 20, 40, 120, 40, hMainWnd, (HMENU)ID_COMBOCOM_0,hInstance,NULL);
          hBaudRate=CreateWindow("Combobox",NULL,WS_CHILD|WS_VISIBLE|WS_VSCROLL|CBS_DROPDOWNLIST, 20, 100, 120, 40, hMainWnd, (HMENU)ID_COMBOCOM_1,hInstance,NULL);
          //Создаем кнопки ;
          hBtn1 = CreateWindow("BUTTON", "Open COM port", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 20, 220, 120, 40, hMainWnd, (HMENU)ID_BUTTON_1, hInstance, NULL);
          hBtn2 = CreateWindow("BUTTON", "New", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 20, 280, 120, 40, hMainWnd, (HMENU)ID_BUTTON_2, hInstance, NULL);
          hBtn3 = CreateWindow("BUTTON", "Send", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 20, 400, 120, 40, hMainWnd, (HMENU)ID_BUTTON_3, hInstance, NULL);
          hBtn4 = CreateWindow("BUTTON", "Choose", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 20, 160, 120, 40, hMainWnd, (HMENU)ID_BUTTON_4, hInstance, NULL);
          hBtn5 = CreateWindow("BUTTON", "Reserved", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP, 20, 340, 120, 40, hMainWnd, (HMENU)ID_BUTTON_5, hInstance, NULL);
          //Заносим значения портов:
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM1");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM2");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM3");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM4");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM5");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM6");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM7");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM8");
          SendMessage(hComboPort, CB_ADDSTRING, 1, (LPARAM)"COM9");
          //Заносим значения скорости:
          SendMessage(hBaudRate, CB_ADDSTRING, 1, (LPARAM)"9600");
          SendMessage(hBaudRate, CB_ADDSTRING, 2, (LPARAM)"19200");
          SendMessage(hBaudRate, CB_ADDSTRING, 3, (LPARAM)"38400");
          SendMessage(hBaudRate, CB_ADDSTRING, 4, (LPARAM)"57600");
          SendMessage(hBaudRate, CB_ADDSTRING, 5, (LPARAM)"115200");
          //--------------------------------------------------------------------------------------------
          SendMessage(hComboPort, CB_SETCURSEL, 0, 0L);  //Делаем текущим первую строчку в меню портов
          SendMessage(hBaudRate, CB_SETCURSEL, 0, 0L);   //Делаем текущим первую строчку в меню скорости
          memdc=CreateCompatibleDC(hdc);                 //создём в памяти контекст, совместимый с нашим
          hbit=CreateCompatibleBitmap(hdc, maxX, maxY);  //создаём картинку нашего окна
          SelectObject(memdc, hbit);                     //делаем её активной в области контекста памяти
          hbrush=CreateSolidBrush(RGB(255,255,255));     //создаём кисть
          SelectObject(memdc, hbrush);                   //делаем её активной
          PatBlt(memdc, 0,0,maxX, maxY, PATCOPY);        //копируем картинку из памяти в наше окно, растянув её на всё окно
          ReleaseDC(hMainWnd, hdc);                      //освобождаем контекст
          ComName[0]=0;                               //изначально имя COM порта не выбрано
          if(TimerEnable)
          {
            SetTimer(hMainWnd, 1, 1, NULL); //создаем таймер для ограничения частоты посылок COM порта в 0,02 сек
          }
          return 0;
        }
        
        case WM_PAINT:
        {
          hdc=BeginPaint(hMainWnd, &ps); 
          //Заголовки над элементами управления
          //-----------------МЕНЮ-ПОРТОВ--------------------------------------------------------------
          SetTextColor(hdc, RGB(255,255,67));
          SetBkMode(hdc, TRANSPARENT);
          TextOut(hdc, 10, 70, WindowText_1, 17); //выводим текст в окно
          //Перерисовка окна
          memdc=CreateCompatibleDC(hdc);
          BitBlt(hdc, 0, 0, maxX, maxY, memdc, 0, 0, SRCCOPY); //копирует в окно сохранённую картинку 
          //-----------------МЕНЮ-СКОРОСТИ------------------------------------------------------------
          SetTextColor(hdc, RGB(255,255,67));
          SetBkMode(hdc, TRANSPARENT);
          TextOut(hdc, 20, 130, WindowText_2, 17); //выводим текст в окно
          //Перерисовка окна
          memdc=CreateCompatibleDC(hdc);
          BitBlt(hdc, 0, 0, maxX, maxY, memdc, 0, 0, SRCCOPY); //копирует в окно сохранённую картинку
          //InitWindow(sx, sy);                                  //рисуем рамку окна тренда
          EndPaint(hMainWnd, &ps);
          return 0;
        }
        
        case WM_TIMER:
        {
          CharWrite = (unsigned char)CharData;
          if(PrtOpen)   //если порт открыт  
          {
             if(hReader) //если поток чтения запущен
             { 
                if(!hWriter) //если поток записи не запущен
                {
                  ResumeThread(hWriter); //пробуждаем поток записи
                }
                WriteThread(&CharWrite); //передаем в функцию потока записи указатель на передаваюмую переменную(char)
                CharData++;  
             }
          }
          return 0;
        }
        
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case ID_BUTTON_1: //если нажата кнопка открытия порта
                    if(!PrtOpen)
                    {
                       COMOpen(ComName, BaudRate, FileName);
                       SetWindowText(hBtn1, "Close COM port");
                    }
                    else
                    {
                       COMClose();
                       SetWindowText(hBtn1, "Open COM port");
                    }
                break;
                
                
                case ID_BUTTON_2:  //если нажата кнопка открытия окна настройки графиков
                {
                  if(!NewWindOpen) //если окно закрыто
                  {
                    cMyRegisterChildClass();
                    chTrWnd = CreateWindowEx(WS_EX_CLIENTEDGE, ctrClassName, "Preset", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 170, 10, 810, 480, NULL, NULL, ctrhInstance, NULL);
                    SetWindowText(hBtn2, "Save changes");
                    NewWindOpen=true;
                  }
                  else
                  {
                    SendMessage(chTrWnd, WM_CLOSE, 0, 0);
                    SetWindowText(hBtn2, "New");
                    NewWindOpen=false;
                  }
                }                       
                break;
 
                
                case ID_BUTTON_3: //если нажата кнопка передачи
                {
                    Write_in_port((unsigned char)CharData);
                    CharData++;
                    return 0;
                }
                break;
                
                case ID_BUTTON_4: //если нажата кнопка подтверждения выбора порта
                {
                  SelectedCom=SendMessage(hComboPort, CB_GETCURSEL, 0, 0L);//Получить из списка текст выделенной строки
                  //Сообщение CB_GETLBTEXT (Get ListBox Text) записывает в строку ComNameBuf текст строки с номером SelectedCom. Для этого она даже не должна быть выделена
                  SendMessage(hComboPort, CB_GETLBTEXT, (WPARAM)SelectedCom, (LPARAM)ComName);
                  SelectedRate=SendMessage(hBaudRate, CB_GETCURSEL, 0, 0L);//Получить из списка номер выделенной строки
                  switch(SelectedRate)
                  {
                     case(0): BaudRate = 9600; break;
                     case(1): BaudRate = 19200; break;
                     case(2): BaudRate = 38400; break;
                     case(3): BaudRate = 57600; break;
                     case(4): BaudRate = 115200; break;
                     default: MessageBox(NULL, "Выберите скорость передачи", "Error", MB_SYSTEMMODAL);break;
                  }
                }
                break;
            }  
            break;
            
        case WM_CLOSE:
            COMClose();
            DestroyWindow(hMainWnd);
            return 0;
 
        case WM_DESTROY:
            
            if(TimerEnable)
            { 
               KillTimer(hMainWnd, 1);
            }
            COMClose();
            PostQuitMessage(0);
            break;      
            
        case WM_KEYDOWN:
            switch(wParam) 
            {
                case VK_ESCAPE:                 
                    SendMessage(hMainWnd, WM_CLOSE, 0, 0);
                    break;
            }
            break;
        
        case WM_SIZE: //при изменении размеров окна, взывается 
           InvalidateRect(hMainWnd, NULL, 1); //сообщение WM_PAINT
           InvalidateRect(hTrWnd, NULL, 1);
           UpdateWindow(hTrWnd);
           
        break;
        
        default:return DefWindowProc(hMainWnd, msg, wParam, lParam);
    }
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.07.2016, 12:16
Ответы с готовыми решениями:

Как закрыть или скрыть основное окно и открыть дочернее, и как потом закрыть дочернее окно и открыть основное
Здравствуйте, передо мной возникла проблема, с которой я не могу справиться. Суть проблемы в том,...

Закрыть дочернее окно и открыть в единственном экземпляре Главное окно
Есть главная форма Main Form , там кнопка Button 1 при нажатии на Button 1 открывыется дочерняя...

Дочернее окно
Доброго времени суток. Продолжаю писать свою программу, возникла проблема. Я пытался сделать, чтобы...

Дочернее окно
Подскажите, плиз, как сделать так чтобы дочернее окно могло перемещаться только внутри...

10
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 12:18  [ТС] 2
trend.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <windows.h>
 
 
WNDCLASSEX tr;        //структура класса окна графиков
WNDCLASSEX ctr;       //структура класса окна настройки графиков
PAINTSTRUCT trps;     //структура рисования графиков
PAINTSTRUCT ctrps;    //структура рисования настройки графиков
HWND hTrWnd;          // Дескриптор окна графиков
HWND chTrWnd;         // Дескриптор окна настройки графиков
HRGN hrgn;
HRGN chrgn;
char trClassName[] = "TrClass"; //имя класса окна графиков
char ctrClassName[] = "cTrClass"; //имя класса окна настройки графиков
int TrendWnd_lx, TrendWnd_ly, TrendWnd_rx, TrendWnd_ry;
int cTrendWnd_lx, cTrendWnd_ly, cTrendWnd_rx, cTrendWnd_ry;
int sx, sy;
int csx, csy;
static HPEN TrendLinePen[8];
static HPEN ZeroLinePen[8];
 
static HPEN DefaultPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));    //карандаш по умолчанию
static HPEN DefaultZeroPen = CreatePen(PS_DOT, 1, RGB(0, 0, 0));  //карандаш для нулевой линии по умолчанию
static HPEN RectanglePen = CreatePen(PS_SOLID, 4, RGB(0, 0, 0));  //карандаш для рисования рамки окна
static HPEN NetLinePen = CreatePen(PS_DOT, 1, RGB(125, 125, 125));//карандаш для рисования сетки окна
 
////////////////////////////////////////////////////////////////////////////////*/
//----------------------------------------------------------------------------------------------------------------------------------------------------
class GRAPH
{
  public:
     GRAPH();                                                            //создает график по умолчанию
     GRAPH(int ZeroPoint, HPEN Z_Pen, HPEN L_Pen);                       //создает настроенный график 
     ~GRAPH();
     void SetZeroPoint(int ZeroPoint){zPoint = TrendWnd_ry + ZeroPoint;} //установка 0 графика по Y
     int  GetZeroPoint(void){return zPoint;}                             //получить нулевую точку
     void SetZeroLinePen(HPEN Pen){ZeroLinePen = Pen;}                   //установка карандаша для нулевой линии 
     void SetLinePen(HPEN Pen){LinePen = Pen;}                           //установка карандаша для линии графика
     void SetLinePoint(int xL_Point, int yL_Point){xPoint = xL_Point; yPoint = yL_Point;}//установка точки графика
     void StartPoint(void){MoveToEx(hdc, TrendWnd_lx, zPoint, NULL);}    //переход к стартовой точке графика
     void DrawLine(HWND hwnd, HDC hdc, int xLinePoint, int yLinePoint);  //рисование линии фрафика
     void PutZeroLine(void);                                             //рисование нулевой линии
  private:
     HPEN ZeroLinePen;    //карандаш для нулевой линии
     HPEN LinePen;        //карандаш для линии графика
     int zPoint;          //точка начала координат графика(нулевая)
     int xPoint;          //X координата точки
     int yPoint;          //Y координата точки
};
 
GRAPH::GRAPH()
{
   ZeroLinePen = DefaultZeroPen;
   LinePen = DefaultPen;
   zPoint = 0; //график начинается в нижнем левом углу окна
   xPoint = 0; //
   yPoint = 0; //
}
 
GRAPH::GRAPH(int ZeroPoint, HPEN Z_Pen, HPEN L_Pen)
{
  SetZeroPoint(ZeroPoint);//выбираем место положения графика
  ZeroLinePen = Z_Pen;    //выбираем вид нулевой линии
  yPoint = zPoint;        //график начинается с нуля
  LinePen = L_Pen;        //выбираем вид линии графика
}
 
GRAPH::~GRAPH()
{
  delete  ZeroLinePen;
  delete  LinePen;
}
 
void GRAPH::PutZeroLine(void)                       //рисуем нулевую линию
{
  SelectObject(hdc, ZeroLinePen);           //выбираем карандаш для нулевой линии
  StartPoint();                             //идем в начало координат(по X-левая точка x оси, Y-точка нулевой линии)
  LineTo(hdc, TrendWnd_rx, zPoint);         //чертим линию до крайней правой точки по X, Y-точка нулевой линии
  SelectObject(hdc, LinePen);               //заранее выбираем карандаш для линии графика
  StartPoint();                             //идем в начало координат
}                                           //так мы подготовились к выводу линии самого графика
 
void GRAPH::DrawLine(HWND hwnd, HDC hdc, int xLinePoint, int yLinePoint)
{ //если раскоментировать то будет как на фото
  //hdc=GetDC(hwnd);                //получаем контекст изображения(функция инициализации передает дескриптор своего окна);
  SelectObject(hdc, LinePen);
  LineTo(hdc, xLinePoint, yLinePoint);
  //ReleaseDC(hwnd, hdc);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////
static GRAPH* graph[8];  //массив объектов для создания и управления линиями графиков
static GRAPH* cgraph[3]; //массив объектов для создания и управления линиями настройки графиков
 
struct adc    //структура для хранения показаний 8 АЦП
{
   char graph1;
   char graph2;
   char graph3;
   char graph4;
   char graph5;
   char graph6;
   char graph7;
   char graph8;
};
 
struct pwm    //структура для хранения установок 3 ШИМ
{
   char vol1;
   char vol2;
   char vol3;
};
//-----------------------------------------------------------------------------------------
 
int InitWindow(int sx, int sy);                          //функция инициализации окна графиков
int cInitWindow(int csx, int csy);                       //функция инициализации окна настройки графиков
ATOM MyRegisterChildClass();                             //функция регистрации класса окна
ATOM cMyRegisterChildClass();                            //функция регистрации класса окна настройки графиков
//void Marker(LONG x, LONG y, HWND hTrWnd);                //для работы с мышью
LRESULT CALLBACK TrGraphProc(HWND, UINT, WPARAM, LPARAM);//обработчик сообщений окна графиков
LRESULT CALLBACK cTrGraphProc(HWND, UINT, WPARAM, LPARAM);//обработчик сообщений окна настройки графиков
0
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 12:20  [ТС] 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
ATOM MyRegisterChildClass()
    {// Заполняем структуру класса окна
       tr.cbSize = sizeof(tr);
       tr.style = CS_HREDRAW | CS_VREDRAW;// Стили класса, в данном случае - окна этого класса будут перерисовываться при изменении размеров по вертикали и горизонтали
       tr.lpfnWndProc = TrGraphProc;// Указатель на функцию, обрабатывающую оконные сообщения
       tr.cbClsExtra = 0;        // Нет дополнительных данных класса 
       tr.cbWndExtra = 0;        // Нет дополнительных данных окна
       tr.hInstance = hInstance; // дескриптор приложения, который регистрирует класс
       tr.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Стандартная иконка
       tr.hCursor = LoadCursor(NULL, IDC_CROSS);   //курсор - перекрестие
       tr.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);// Цвет фона рабочей области окна
       tr.lpszMenuName = NULL;   // Нет меню
       tr.lpszClassName = "TrClass"; // Имя класса окна
       tr.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
       return RegisterClassEx(&tr);
    }
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
ATOM cMyRegisterChildClass()
{
// Заполняем структуру класса окна
       ctr.cbSize = sizeof(ctr);
       ctr.style = CS_HREDRAW | CS_VREDRAW;// Стили класса, в данном случае - окна этого класса будут перерисовываться при изменении размеров по вертикали и горизонтали
       ctr.lpfnWndProc = cTrGraphProc;// Указатель на функцию, обрабатывающую оконные сообщения
       ctr.cbClsExtra = 0;        // Нет дополнительных данных класса 
       ctr.cbWndExtra = 0;        // Нет дополнительных данных окна
       ctr.hInstance = hInstance; // дескриптор приложения, который регистрирует класс
       ctr.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Стандартная иконка
       ctr.hCursor = LoadCursor(NULL, IDC_CROSS);   //курсор - перекрестие
       ctr.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);// Цвет фона рабочей области окна
       ctr.lpszMenuName = NULL;   // Нет меню
       ctr.lpszClassName = "cTrClass"; // Имя класса окна
       ctr.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
       return RegisterClassEx(&ctr);
}   
 
//--------------------------------------------------------------------------------------------------------------------------------------------  
    
int InitWindow(int sx, int sy)
{  
   int x, y;         //временные переменные координат для черчения сетки окна
   TrendWnd_lx = 0;  //левая X координата 
   TrendWnd_ly = 0;  //левая Y координата
   TrendWnd_rx = sx; //правая X координата - размер окна по X
   TrendWnd_ry = -sy;//правая Y координата - размер окна по Y(костыль)
   
   hbrush = CreateSolidBrush(RGB(255, 255, 255)); //кисть для заливки окна графика белым цветом
   SetMapMode(hdc, MM_ISOTROPIC);                 //текущий режим отображения 
   SetViewportExtEx(hdc, sx, sy, NULL);           //физический размер области экрана в пикселах
   SetWindowExtEx(hdc,  sx, sy, NULL);            //логические размеры окна в пикселах
   
   SelectObject(hdc, hbrush);       //заливаем окно белым
   SelectObject(hdc, RectanglePen); //выбираем карандаш для рисования окна рамки
   Rectangle(hdc, TrendWnd_lx, TrendWnd_ly, TrendWnd_rx, TrendWnd_ry);//рисуем рамку окна
   for (x = TrendWnd_lx; x < TrendWnd_rx; x += (TrendWnd_rx/10))//чертим вертикальные линии
   {
      SelectObject(hdc, NetLinePen);//выбираем карандаш для рисования сетки
      MoveToEx(hdc, x, TrendWnd_ly, NULL);//координаты по X увеличиваются
      LineTo(hdc, x, -TrendWnd_ry); //координаты по Y не меняются(костыль)
   }
   for (y = TrendWnd_ly; y < -TrendWnd_ry; y += ((-TrendWnd_ry)/10))//чертим горизонтальные линии(костыль)
   {
      MoveToEx(hdc, TrendWnd_lx, y, NULL);//координаты по X не меняются
      LineTo(hdc, TrendWnd_rx, y);        //координаты по Y увеличиваются
   }
   //костыли были нужны для следующей операции, иначе не работало
   SetWindowExtEx(hdc,  sx, -sy, NULL);   //логические размеры окна в пикселах, ось Y вверх
   //...................................................
  //инициализируем массив кистей графиков для объектов класса GRAPH(линии сплошные разных цветов)
  TrendLinePen[0]=CreatePen(PS_SOLID, 1, RGB(250, 0, 0));
  TrendLinePen[1]=CreatePen(PS_SOLID, 1, RGB(0, 250, 0));
  TrendLinePen[2]=CreatePen(PS_SOLID, 1, RGB(0, 0, 250));
  TrendLinePen[3]=CreatePen(PS_SOLID, 1, RGB(250, 250, 0));
  TrendLinePen[4]=CreatePen(PS_SOLID, 1, RGB(250, 0, 250));
  TrendLinePen[5]=CreatePen(PS_SOLID, 1, RGB(0, 250, 250));
  TrendLinePen[6]=CreatePen(PS_SOLID, 1, RGB(250, 125, 65));
  TrendLinePen[7]=CreatePen(PS_SOLID, 1, RGB(65, 125, 250));
  //инициализируем массив кистей нулевых линий для объектов класса GRAPH(линии из точек разных цветов)
  ZeroLinePen[0]=CreatePen(PS_DOT, 1, RGB(250, 0, 0));
  ZeroLinePen[1]=CreatePen(PS_DOT, 1, RGB(0, 250, 0));
  ZeroLinePen[2]=CreatePen(PS_DOT, 1, RGB(0, 0, 250));
  ZeroLinePen[3]=CreatePen(PS_DOT, 1, RGB(250, 250, 0));
  ZeroLinePen[4]=CreatePen(PS_DOT, 1, RGB(250, 0, 250));
  ZeroLinePen[5]=CreatePen(PS_DOT, 1, RGB(0, 250, 250));
  ZeroLinePen[6]=CreatePen(PS_DOT, 1, RGB(250, 125, 65));
  ZeroLinePen[7]=CreatePen(PS_DOT, 1, RGB(65, 125, 250));
  
  for(int i=0; i<8; i++)//циклически инициализируем массив указателей на объекты класса GRAPH
  {
    graph[i] = new GRAPH(i*50 + 10, ZeroLinePen[i], TrendLinePen[i]);//первая линия приподнимается на 10 пикселей
  }                                                                  //остальные от нее и друг от друга на 50 пик.
   //...................................................
   ///////////////////////////
   for(int i = 0; i<8; i++)       //циклически
   { 
     graph[i]->StartPoint();      //идем к стартовой позиции
     graph[i]->PutZeroLine();     //выводим нулевую линию
   } 
   
   for(int x, y, i = 0; i<8; i++)       //циклически
   { //x, y временные переменные для X и Y координат
     graph[i]->StartPoint();      //идем к стартовой позиции
     for(x=TrendWnd_lx, y=graph[i]->GetZeroPoint(); x<TrendWnd_rx; x+=10, y+=2)//чертим линию, увеличивая X на 10, Y на 2
     {  
        graph[i]->DrawLine(hTrWnd, hdc, x, y);  //выводим линию графика
     }
   } 
   ///////////////////////////
}
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
int cInitWindow(int csx, int csy)
{
   int x, y;         //временные переменные координат для черчения сетки окна
   cTrendWnd_lx = 0;  //левая X координата 
   cTrendWnd_ly = 0;  //левая Y координата
   cTrendWnd_rx = csx; //правая X координата - размер окна по X
   cTrendWnd_ry = -csy;//правая Y координата - размер окна по Y(костыль)
   
   hbrush = CreateSolidBrush(RGB(255, 255, 255)); //кисть для заливки окна графика белым цветом
   SetMapMode(hdc, MM_ISOTROPIC);                 //текущий режим отображения 
   SetViewportExtEx(hdc, csx, csy, NULL);           //физический размер области экрана в пикселах
   SetWindowExtEx(hdc,  csx, csy, NULL);            //логические размеры окна в пикселах
   
   SelectObject(hdc, hbrush);       //заливаем окно белым
   SelectObject(hdc, RectanglePen); //выбираем карандаш для рисования окна рамки
   Rectangle(hdc, cTrendWnd_lx, cTrendWnd_ly, cTrendWnd_rx, cTrendWnd_ry);//рисуем рамку окна
   for (x = cTrendWnd_lx; x < cTrendWnd_rx; x += (cTrendWnd_rx/10))//чертим вертикальные линии
   {
      SelectObject(hdc, NetLinePen);//выбираем карандаш для рисования сетки
      MoveToEx(hdc, x, cTrendWnd_ly, NULL);//координаты по X увеличиваются
      LineTo(hdc, x, -cTrendWnd_ry); //координаты по Y не меняются(костыль)
   }
   for (y = cTrendWnd_ly; y < -cTrendWnd_ry; y += ((-cTrendWnd_ry)/10))//чертим горизонтальные линии(костыль)
   {
      MoveToEx(hdc, cTrendWnd_lx, y, NULL);//координаты по X не меняются
      LineTo(hdc, cTrendWnd_rx, y);        //координаты по Y увеличиваются
   }
   //костыли были нужны для следующей операции, иначе не работало
   SetWindowExtEx(hdc,  csx, -csy, NULL);   //логические размеры окна в пикселах, ось Y вверх
   //...................................................
  //инициализируем массив кистей графиков для объектов класса GRAPH(линии сплошные разных цветов)
  TrendLinePen[0]=CreatePen(PS_SOLID, 1, RGB(250, 0, 0));
  TrendLinePen[1]=CreatePen(PS_SOLID, 1, RGB(0, 250, 0));
  TrendLinePen[2]=CreatePen(PS_SOLID, 1, RGB(0, 0, 250));
  //инициализируем массив кистей нулевых линий для объектов класса GRAPH(линии из точек разных цветов)
  ZeroLinePen[0]=CreatePen(PS_DOT, 1, RGB(250, 0, 0));
  ZeroLinePen[1]=CreatePen(PS_DOT, 1, RGB(0, 250, 0));
  ZeroLinePen[2]=CreatePen(PS_DOT, 1, RGB(0, 0, 250));
  
  for(int i=0; i<3; i++)//циклически инициализируем массив указателей на объекты класса GRAPH
  {
    cgraph[i] = new GRAPH(i*50 + 10, ZeroLinePen[i], TrendLinePen[i]);//первая линия приподнимается на 10 пикселей
  }                                                                  //остальные от нее и друг от друга на 50 пик.
   //...................................................
   ///////////////////////////
   for(int i = 0; i<3; i++)       //циклически
   { 
     cgraph[i]->StartPoint();      //идем к стартовой позиции
     cgraph[i]->PutZeroLine();     //выводим нулевую линию
   } 
   
   for(int x, y, i = 0; i<3; i++)       //циклически
   { //x, y временные переменные для X и Y координат
     cgraph[i]->StartPoint();      //идем к стартовой позиции
     for(x=cTrendWnd_lx, y=cgraph[i]->GetZeroPoint(); x<cTrendWnd_rx; x++)//чертим линию, увеличивая X на 1
     {  
        cgraph[i]->DrawLine(chTrWnd, hdc, x, y);  //выводим линию графика
     }
   } 
   ///////////////////////////
}
//-------------------------------------------------------------------------------------------------------------------------------------------
 
//--------------------------------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK TrGraphProc(HWND hTrWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
   adc myTrend;
   int nCmdShow;
   switch (msg) 
    {
        case WM_CREATE:
        { 
          ShowWindow(hTrWnd, nCmdShow);
          UpdateWindow(hTrWnd);
          sx = LOWORD(lParam); //ширина окна
          sy = HIWORD(lParam); //высота окна
          break;
        }
        
        case WM_PAINT:
        {
          
          hdc=BeginPaint(hTrWnd, &trps); 
          InitWindow(810, 440);                                  //рисуем рамку окна тренда
          EndPaint(hTrWnd, &trps);
          break;
        }
        
        case WM_CLOSE:
            DestroyWindow(hTrWnd);
            break;
 
        case WM_DESTROY:
            DeleteObject(RectanglePen);
            DeleteObject(NetLinePen);
            for(int i=0; i<8; i++)
            {
              DeleteObject(graph[i]);
            }
            DeleteObject(hbrush);
            PostQuitMessage(0);
            break;      
            
        case WM_KEYDOWN:
            switch(wParam) 
            {
                case VK_ESCAPE:                 
                    SendMessage(hTrWnd, WM_CLOSE, 0, 0);
                    break;
            }
            break;
        
        default:return DefWindowProc(hTrWnd, msg, wParam, lParam);break;
    }
}
 
//-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
LRESULT CALLBACK cTrGraphProc(HWND chTrWnd, UINT ctrmsg, WPARAM wParam, LPARAM lParam)
{
   pwm myVoltage;
   int cnCmdShow;
   switch (ctrmsg) 
    {
        case WM_CREATE:
        { 
          ShowWindow(chTrWnd, cnCmdShow);
          UpdateWindow(chTrWnd);
          csx = LOWORD(lParam); //ширина окна
          csy = HIWORD(lParam); //высота окна
          break;
        }
         
        case WM_PAINT:
        {
    
          hdc=BeginPaint(chTrWnd, &ctrps); 
          InitWindow(810, 440);                                  //рисуем рамку окна тренда
          EndPaint(chTrWnd, &ctrps);
          break;
        }
        
        case WM_CLOSE:
            DestroyWindow(chTrWnd);
            break;
 
        case WM_DESTROY:
            DeleteObject(RectanglePen);
            DeleteObject(NetLinePen);
            for(int i=0; i<3; i++)
            {
              DeleteObject(cgraph[i]);
            }
            DeleteObject(hbrush);
            PostQuitMessage(0);
            break;      
            
        case WM_KEYDOWN:
            switch(wParam) 
            {
                case VK_ESCAPE:                 
                    SendMessage(chTrWnd, WM_CLOSE, 0, 0);
                    break;
            }
            break;
        
        default:return DefWindowProc(chTrWnd, ctrmsg, wParam, lParam);break;
    }
}
Надеюсь, что коментарии достаточно подробны
0
897 / 418 / 159
Регистрация: 02.04.2014
Сообщений: 1,206
22.07.2016, 18:39 4
а что такое #include "com.h" ? где его брать?
ты думаешь всем так интересно копировать тыщу строк твоего кода, создавать дополнительные файлы, вставлять их туда, добавлять в проект и т.п? Выкладывал бы сразу архив с проектом, так больше шансов, что кто-нибудь займется
0
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 18:57  [ТС] 5
Я незнаю, как архив добавлять, картинки и те модер добавил com.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <windows.h>
#include <stdint.h>     //uint8_t - 8 битный int
#include <process.h>    //для функций _beginthreadex
#include <string>       //для работы со строками
#include <io.h>         //для работы с файлами
#include <thread>       //для работы с потоками
#include "error_code.h"
////////////////////////////////////////////////////
#include <fstream> // для файловых потоков
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
#define BUFSIZE 255     //размер приемного и передающего буферов
#define File_Mapping_Length  1//размер файла проекции по умолчанию
static HANDLE hSerial;   //дескриптор com порта 
static HANDLE hReader;   //дескриптор потока чтения
static HANDLE hWriter;   //дескриптор потока записи
static HANDLE hFileReader;//дескриптор потока чтения файла
static HANDLE hFileWriter;//дескриптор потока записи файла
static HANDLE hFile;     //дескриптор физического файла 
static HANDLE hMapFile;  //дескриптор проецируемого файла
fstream file;            // создать входной/выходной файл(не API)
DWORD dwFileSize;        //размер файла
unsigned char* dataPtr;  //указатель на участок памяти с отображением
LPCTSTR  sf_name = "com_file"; //имя проекции файла
bool fl=0;               //флаг, указывающий на успешность операций записи (1 - успешно, 0 - не успешно)
bool PrtOpen=0;          //флаг, указывающий на успешность открытия порта (1 - успешно, 0 - не успешно)
//PDWORD counter = 0;      //счётчик принятых байтов, обнуляется при каждом открытии порта
unsigned char CharRead, CharWrite;   //приёмная и передающая переменные
 
//эти структуры необходимо объявить глобально, иначе программа не будет работать правильно
OVERLAPPED overlappedread;           //будем использовать для операций чтения
OVERLAPPED overlappedwrite;          //будем использовать для операций записи 
OVERLAPPED overlappedfileread;       //будем использовать для операций чтения файла
OVERLAPPED overlappedfilewrite;      //будем использовать для операций записи файла
unsigned __stdcall ReadThread(void* param);    //функция потока чтения в стиле C++
unsigned __stdcall WriteThread(void* param);   //функция потока записи в стиле C++
unsigned __stdcall ReadFileThread(void* param); //функция потока чтения файла в стиле C++
unsigned __stdcall WriteFileThread(void* param);//функция потока записи файла в стиле C++
DWORD ResumeThread(HANDLE hThread);            //функция запуска потока
DWORD SuspendThread(HANDLE hThread);           //функция останова потока
void COMOpen(char ComName[], int Baudrate, char FileName[]);    //открыть порт
void COMClose(void);                     //закрыть порт
void Write_in_port(unsigned char data);  //записать в порт
 
 
 
//---------------------------------------------------------------------------
 
//функция открытия и инициализации порта
void COMOpen(char ComName[], int Baudrate, char FileName[])
{
 std::string portname;   //имя порта (например, "COM1", "COM2" и т.д.)
 std::string filename;   //имя файла, для записи данных, полученных из порта
 DCB dcb;                //структура для общей инициализации порта DCB
 COMMTIMEOUTS timeouts;  //структура для установки таймаутов
 if (ComName[0]==0)
 {
    MessageBox(NULL, "Выберите порт", "Error", MB_SYSTEMMODAL);
 }
 else
 {
    portname = ComName; //получить имя выбранного порта
    filename = FileName;//получить имя файла
 }
 //открыть порт, для асинхронных операций обязательно нужно указать флаг FILE_FLAG_OVERLAPPED
 hSerial = CreateFile(portname.c_str(),GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
 //здесь:
 // - portname.c_str() - имя порта в качестве имени файла, c_str() преобразует строку типа String в строку в виде массива типа char, иначе функция не примет
 // - GENERIC_READ | GENERIC_WRITE - доступ к порту на чтение/записть
 // - 0 - порт не может быть общедоступным (shared)
 // - NULL - дескриптор порта не наследуется, используется дескриптор безопасности по умолчанию
 // - OPEN_EXISTING - порт должен открываться как уже существующий файл
 // - FILE_FLAG_OVERLAPPED - этот флаг указывает на использование асинхронных операций
 // - NULL - указатель на файл шаблона не используется при работе с портами
 
 if(hSerial == INVALID_HANDLE_VALUE)            //если ошибка открытия порта
  {
   MessageBox(NULL, "Не удалось открыть порт", "Error", MB_SYSTEMMODAL);       //вывести сообщение в строке состояния
   return;
  }
 
 //инициализация порта
 
 dcb.DCBlength = sizeof(DCB);   //в первое поле структуры DCB необходимо занести её длину, она будет использоваться функциями настройки порта для контроля корректности структуры
 
 //считать структуру DCB из порта
 if(!GetCommState(hSerial, &dcb))   //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
  {
   COMClose();
   MessageBox(NULL, "Не удалось считать DCB", "Error", MB_SYSTEMMODAL);
   return;
  }
 
 //инициализация структуры DCB
 dcb.BaudRate = Baudrate;                               //задаём скорость передачи в бодах
 dcb.fBinary = TRUE;                                    //включаем двоичный режим обмена
 dcb.fOutxCtsFlow = FALSE;                              //выключаем режим слежения за сигналом CTS
 dcb.fOutxDsrFlow = FALSE;                              //выключаем режим слежения за сигналом DSR
 dcb.fDtrControl = DTR_CONTROL_DISABLE;                 //отключаем использование линии DTR
 dcb.fDsrSensitivity = FALSE;                           //отключаем восприимчивость драйвера к состоянию линии DSR
 dcb.fNull = FALSE;                                     //разрешить приём нулевых байтов
 dcb.fRtsControl = RTS_CONTROL_DISABLE;                 //отключаем использование линии RTS
 dcb.fAbortOnError = FALSE;                             //отключаем остановку всех операций чтения/записи при ошибке
 dcb.ByteSize = 8;                                      //задаём 8 бит в байте
 dcb.Parity = 0;                                        //отключаем проверку чётности
 dcb.StopBits = 2;                                      //задаём два стоп-бита
 
 //загрузить структуру DCB в порт
 if(!SetCommState(hSerial, &dcb))   //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
  {
   COMClose();
   MessageBox(NULL, "Не удалось установить DCB", "Error", MB_SYSTEMMODAL);
   return;
  }
 
 //установить таймауты
 timeouts.ReadIntervalTimeout = 0;      //таймаут между двумя символами
 timeouts.ReadTotalTimeoutMultiplier = 0;   //общий таймаут операции чтения
 timeouts.ReadTotalTimeoutConstant = 0;         //константа для общего таймаута операции чтения
 timeouts.WriteTotalTimeoutMultiplier = 0;      //общий таймаут операции записи
 timeouts.WriteTotalTimeoutConstant = 0;        //константа для общего таймаута операции записи
 
 //записать структуру таймаутов в порт
 if(!SetCommTimeouts(hSerial, &timeouts))   //если не удалось - закрыть порт и вывести сообщение об ошибке в строке состояния
  {
   COMClose();
   MessageBox(NULL, "Не удалось установить тайм-ауты", "Error", MB_SYSTEMMODAL);
   return;
  }
 
 //установить размеры очередей приёма и передачи
 SetupComm(hSerial,2000,2000);
 PrtOpen=1;
 //создать или открыть существующий файл для записи принимаемых данных
 hFile = CreateFile
        (
            filename.c_str(),                  //имя файла
            GENERIC_READ|GENERIC_WRITE,        //режим доступа, разрешены и чтение и запись
            FILE_SHARE_READ|FILE_SHARE_WRITE,  //совместный доступ
            NULL,                              //дескриптор не может быть унаследован
            OPEN_ALWAYS,                       //открываем файл, либо создаем и открываем
            FILE_ATTRIBUTE_NORMAL,             //обычный файл
            NULL                               //дескр.шаблона файла
        ); 
 if(hFile==INVALID_HANDLE_VALUE)          //если произошла ошибка открытия файла
 {
    MessageBox(NULL, "Ошибка открытия файла", "Error", MB_SYSTEMMODAL);  //вывести сообщение об этом в командной строке
 }
 else
 {
    dwFileSize = GetFileSize(hFile, NULL);  //получаем размер файла
    if(dwFileSize == INVALID_FILE_SIZE)
    {
       MessageBox(NULL, "Не удалось получить размер файла", "Error", MB_SYSTEMMODAL);       //вывести сообщение в строке состояния
       CloseHandle(hFile);
    }
    
    if(dwFileSize == 0)                 //если файл на диске имеет нулевой размер
    {
       dwFileSize = File_Mapping_Length;//задаем размер проекции по умолчанию
    }
    
    if(hMapFile == NULL)                //если проекции файла еще не существует
    {
       hMapFile = CreateFileMapping     //создаем проекцию файла
      ( 
          hFile,         //дескриптор физического файла
          NULL,          //дескриптор не может быть унаследован
          PAGE_READWRITE,//флажки защиты доступа (чтение и запись)
          0,             //старшие байты размера 
          dwFileSize,    //младшие байты размера
          sf_name        //имя проекции sf_name
      );
    }
 
    if(hMapFile == NULL) //если ошибка проекции файла
    {
       MessageBox(NULL, "Не удалось создать проекцию файла", "Error", MB_SYSTEMMODAL);       //вывести сообщение в строке состояния
       CloseHandle(hFile);
    }
    else
    {
       dataPtr = (unsigned char*)MapViewOfFile
       (
          hMapFile,       //дескриптор проекции файла 
          FILE_MAP_WRITE,    //полный доступ для чтения и записи
          0,                 //смещение в файле для отображения
          0,                 //как 64–битное значение
          dwFileSize         //размер представления 
        );
    } 
 }
 MessageBox(NULL, "Порт открыт", "Notice", MB_SYSTEMMODAL); 
 PurgeComm(hSerial, PURGE_RXCLEAR); //очистить принимающий буфер порта
 PrtOpen=1;             //выставляем флаг в "порт открыт" 
 hReader =(HANDLE)_beginthreadex(NULL, 0, ReadThread, &CharRead, CREATE_SUSPENDED, NULL); //создаем поток чтения в остановленном состоянии, дескриптор преобразовывается явно в (HANDLE)
 hWriter =(HANDLE)_beginthreadex(NULL, 0, WriteThread, &CharWrite, CREATE_SUSPENDED, NULL);//создаем поток записи в остановленном состоянии, дескриптор преобразовывается явно в (HANDLE)
 //hFileReader =(HANDLE)_beginthreadex(NULL, 0, WriteThread, &CharWrite, CREATE_SUSPENDED, NULL);//создаем поток чтения в остановленном состоянии, дескриптор преобразовывается явно в (HANDLE)
 //hFileWriter =(HANDLE)_beginthreadex(NULL, 0, WriteThread, &CharWrite, CREATE_SUSPENDED, NULL);//создаем поток записи в остановленном состоянии, дескриптор преобразовывается явно в (HANDLE)
 ResumeThread(hReader); //пробуждаем поток чтения
}    
 
//---------------------------------------------------------------------------
0
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 18:57  [ТС] 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//функция закрытия порта
void COMClose()
{
//Примечание: так как при прерывании потоков, созданных с помощью функций WinAPI, функцией TerminateThread
//        поток может быть прерван жёстко, в любом месте своего выполнения, то освобождать дескриптор
//        сигнального объекта-события, находящегося в структуре типа OVERLAPPED, связанной с потоком,
//        следует не внутри кода потока, а отдельно, после вызова функции TerminateThread.
//        После чего нужно освободить и сам дескриптор потока.
 
 if(hWriter)        //если поток записи работает, завершить его; проверка if(hWriter) обязательна, иначе возникают ошибки
  {TerminateThread(hWriter,0);
   CloseHandle(overlappedwrite.hEvent); //нужно закрыть объект-событие
   CloseHandle(hWriter);
  }
 if(hReader)        //если поток чтения работает, завершить его; проверка if(hReader) обязательна, иначе возникают ошибки
  {TerminateThread(hReader,0);
   CloseHandle(overlappedread.hEvent);  //нужно закрыть объект-событие
   CloseHandle(hReader);
  }
 
 UnmapViewOfFile(dataPtr);
 CloseHandle(hSerial);  //закрыть порт
 hSerial=0;             //обнулить переменную для дескриптора порта
 CloseHandle(hMapFile); //закрыть проекцию файла
 hMapFile=0;            //обнулить проекцию файла
 CloseHandle(hFile);    //закрыть файл, в который велась запись принимаемых данных
 hFile=0;               //обнулить переменную для дескриптора файла
 PrtOpen=0;             //выставляем флаг в "порт закрыт" 
 MessageBox(NULL, "Порт закрыт", "Notice", MB_SYSTEMMODAL);
}
 
//---------------------------------------------------------------------------
 
//главная функция потока, реализует приём байтов из COM-порта
unsigned __stdcall ReadThread(void* param)
{
 COMSTAT comstat;                                               //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
 DWORD Bytes_to_Read, temp, mask, signal;                       //переменная temp используется в качестве заглушки
 DWORD Bytes_to_Write;                                          //счетчик записаных байт
 overlappedread.hEvent = CreateEvent(NULL, true, true, NULL);   //создать сигнальный объект-событие для асинхронных операций
 SetCommMask(hSerial, EV_RXCHAR);                               //установить маску на срабатывание по событию приёма байта в порт
 while(1)                                                       //пока поток не будет прерван, выполняем цикл
 {
   WaitCommEvent(hSerial, &mask, &overlappedread);                  //ожидать события приёма байта (это и есть перекрываемая операция)
   signal = WaitForSingleObject(overlappedread.hEvent, INFINITE);   //приостановить поток до прихода байта
   if(signal == WAIT_OBJECT_0)                                      //если событие прихода байта произошло
    {
     if(GetOverlappedResult(hSerial, &overlappedread, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
      if((mask & EV_RXCHAR)!=0)                                     //если произошло именно событие прихода байта
       {
        ClearCommError(hSerial, &temp, &comstat);                   //нужно заполнить структуру COMSTAT
        Bytes_to_Read = comstat.cbInQue;                            //и получить из неё количество принятых байтов
        if(Bytes_to_Read)                                           //если действительно есть байты для чтения
        {
           ReadFile(hSerial, (TCHAR*)param, Bytes_to_Read, &temp, &overlappedread);    //прочитать байты из порта в буфер программы
           //counter+=Bytes_to_Read;                                                   //увеличиваем счётчик байтов
           WriteFile(hFile, &CharRead, sizeof(CharRead), &Bytes_to_Write, NULL);       //записать в файл данные из приёмного буфера 
        }
        memset((TCHAR*)param, 0, sizeof(CharRead));                 //очистить буфер (чтобы данные не накладывались друг на друга)
       }
    }
  }
}
 
//---------------------------------------------------------------------------
 
//главная функция потока, выполняет передачу байтов из буфера в COM-порт 
unsigned __stdcall WriteThread(void* param)//param это и есть BufferWrite или CharWrite
{
 if(PrtOpen)    //если COM порт открыт
 {
   DWORD temp, signal;  //temp - переменная-заглушка
   bool CykleEnable = 1;
   overlappedwrite.hEvent = CreateEvent(NULL, true, true, NULL);      //создать событие
   while(CykleEnable) //если CykleEnable заменить на PrtOpen, то передача будет идти непрерывно
   {
     WriteFile(hSerial, (TCHAR*)param, strlen((TCHAR*)param), &temp, &overlappedwrite);  //записать байты в порт (перекрываемая операция!)
     signal = WaitForSingleObject(overlappedwrite.hEvent, INFINITE);      //приостановить поток, пока не завершится перекрываемая операция WriteFile
 
     if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(hSerial, &overlappedwrite, &temp, true))) //если операция завершилась успешно
     {
        CykleEnable = 0; //завершаем цикл
     }
     else 
     {
       MessageBox(NULL, "Ошибка передачи", "Error", MB_SYSTEMMODAL);//иначе вывести в строке состояния сообщение об ошибке
     }   
     SuspendThread(hWriter);
   }
 }
 else
 {
   MessageBox(NULL, "Сначала откройте COM порт", "Notice", MB_SYSTEMMODAL);   //вывести сообщение об этом в строке состояния
 }
  
}
 
//---------------------------------------------------------------------------
/*
unsigned __stdcall ReadFileThread(void* param)
{
   overlappedfileread.hEvent = CreateEvent(NULL, true, true, NULL); //создать сигнальный объект-событие для асинхронных операций
  
}
 
//---------------------------------------------------------------------------
 
unsigned __stdcall ReadFileThread(void* param)
{
   overlappedfilewrite.hEvent = CreateEvent(NULL, true, true, NULL);    //создать сигнальный объект-событие для асинхронных операций
   
}
*/
//---------------------------------------------------------------------------
void Write_in_port(unsigned char data)
{
   CharWrite = data;
   if(PrtOpen)   //если порт открыт
   { 
      if(!hWriter) //если поток записи не запущен
      {
         ResumeThread(hWriter); //пробуждаем поток записи
      }
      WriteThread(&CharWrite); //передаем в функцию потока записи указатель на передаваюмую переменную(char) 
   }
   else
   {
      MessageBox(NULL, "Порт не открыт", "Error", MB_SYSTEMMODAL);
   }
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
30335 / 19827 / 7750
Регистрация: 22.10.2011
Сообщений: 34,575
Записей в блоге: 6
22.07.2016, 20:12 7
Цитата Сообщение от Lincer Посмотреть сообщение
Я незнаю, как архив добавлять
Нажать на кнопку "Управление вложениями", чуть ниже поля для ввода текста.
0
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 21:42  [ТС] 8
Ок, вот проект для Dev C++
0
Вложения
Тип файла: rar Com_Port_ver_1.rar (275.5 Кб, 4 просмотров)
5 / 5 / 3
Регистрация: 15.07.2016
Сообщений: 13
22.07.2016, 22:57 9
Lincer, оставь "PostQuitMessage()" только в основном WndProc()
1
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
22.07.2016, 23:13  [ТС] 10
С завершением приложения, при закрытии дополнительного окна разобрались, теперь желательно в нем увидеть три прямых линии, вместо восьми наклонных.
0
0 / 0 / 0
Регистрация: 06.06.2016
Сообщений: 47
24.07.2016, 23:32  [ТС] 11
Причина ошибки была до обидного простой
В LRESULT CALLBACK cTrGraphProc(HWND chTrWnd, UINT ctrmsg, WPARAM wParam, LPARAM lParam) окно нужно было инициализировать функцией cInitWindow(850, 450), а не InitWindow(850, 450).
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.07.2016, 23:32

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Дочернее окно
Как создать окно наподобии ShowDialog но с возможностью динамически добавлять UserControl?...

Дочернее окно
Задание: дочернее окно должно убегать от курсора мыши в пределах рабочей области родительского...

Дочернее окно
Есть код, в нём создал главное окно, и дочернее. Но как сделать так, что бы по щелчку на дочернее...

Дочернее окно
В общем, такая проблема, при нажатии на кнопку открывается новая форма, нужно сделать так, чтобы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.