6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
1

Как совместить win32 форму и консольное приложение?

09.02.2018, 15:43. Показов 3048. Ответов 19

Author24 — интернет-сервис помощи студентам
Хотелось бы узнать, возможно ли совместить вин32 форму и консольное приложение? Суть в том что мне нужно чтобы в основном (консольном приложении) в главном цикле обрабатывались определенные данные, а вин32 форма должна быть пользовательским интерфейсом, отображать некоторые данные. У меня есть некоторый код который позволяет создать окно вин32 из консоли но проблема в том, что когда запускается это окно - основной цикл перестает выполняться и выполняется только цикл winmain функции. Я пробовал запустить её в отдельном потоке, но так как поток не возвращает управление то проблема никуда не девается.
Собственно что я делаю не так?

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
#include <iostream>
#include <thread>
 
#include "Device.h"
 
 
void DeviceTask();
 
 
int main(int argc, char* argv[])
{
 
    std::thread dtask(DeviceTask);
    
    bool jnState = true;
    
    dtask.join(); Sleep(500);
    
    while (true)
    {
 
        std::cout<<"Main loop processing..\n";
        Sleep(500);
    }
 
    return 0;   }
 
void DeviceTask()
{
    CDevice * App;
    App  = new CDevice();           std::cout<<"Device create\n";
    App ->InitializeWindow();       std::cout<<"Device init & run \n";
}
// вот такое нечто
Добавлено через 15 минут
ребят, никто не шарит?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.02.2018, 15:43
Ответы с готовыми решениями:

Как украсить консольное приложение Win32?
Мне надо &quot;украсить&quot; консольную программу Win32, но как я не знаю!!! Подскажите пожалуйста!!!!

Подскажите пожалуйста как написать консольное приложение win32, которое принимает на вход путь к папке
Нужно написать консольное приложение win32, которое принимает на вход путь к папке

Как соединить форму и консольное приложение
здравствуйте поиск по форуму и по интернетам мне нечего не дал так что обращаюсь в высшую...

Как перенести консольное приложение в форму
Есть программа на консольки, ее нужно перенести в форму, а именно в TextBox. Знаю, что это нужно...

19
Эксперт С++
3694 / 2828 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 22
09.02.2018, 16:01 2
как вариант Win32 приложение убрать в dll.
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
09.02.2018, 16:12  [ТС] 3
_lunar_, а другого варианта нет? не очень хочется из-за формы тащить с собой библиотеку dll
0
Эксперт С++
3694 / 2828 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 22
09.02.2018, 16:17 4
Цитата Сообщение от IronnMann Посмотреть сообщение
а другого варианта нет?
может и есть, dll это первое что пришло в голову.
сейчас времени нет, вечером помозгую эту тему.
0
3958 / 2504 / 420
Регистрация: 09.09.2017
Сообщений: 10,999
09.02.2018, 16:40 5
Так ведь задача не озвучена.
Достаточно ли просто запустить ядро из GUI и посмотреть код возврата / stdout?
Или они должны обмениваться данными в процессе работы? Какого типа данные, сколько их, насколько опасны ошибки?
Если нужно ядро и GUI, запускающее его и отслеживающее прогресс выполнения, достаточно thread'ов. Вынести в общую переменную текущий прогресс и пусть оболочка его отрисовывает. Если нужна какая-то реакция на пользователя, можно перенаправить stdin, stdout или использовать собственные каналы (pipes). А может удобнее будет прокинуть взаимодействие через сеть.
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
09.02.2018, 17:09  [ТС] 6
COKPOWEHEU, Основная программа - консольная, назовем её ядром. В ней в цикле выполняются расчеты, и этот цикл должен работать всегда. А GUI он как оболочка. В ядре я обрабатываю звук, еще некоторые данные, а от формы мне нужно получать сообщения о нажатии клавиш допустим, или клик на форме, и вывести на неё битмап например
0
2783 / 1936 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
09.02.2018, 17:12 7
Цитата Сообщение от IronnMann Посмотреть сообщение
Хотелось бы узнать, возможно ли совместить вин32 форму и консольное приложение?
Можно. Добавляешь в вин32-форму текстовое поле, меняешь все cout на stringstream, содержимое stringstream по какому ни будь таймеру скидываешь в текстовое поле. Итого, получаешь такую консольку, встроенную в вин32 форму.
C++
1
2
3
std::stringstream stream;
stream<<1234;
ToWinForm(stream.str());//ToWinForm сам пили
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
09.02.2018, 17:16  [ТС] 8
COKPOWEHEU, вот к примеру игровой цикл делают один, и он обрабатывает события движка, и проч. а чтобы в windows сделать окно, там тоже надо использовать цикл обработки сообщений окна. Некоторые конечно идут по простому пути и делают обработку событий движка прямо в основном цикле формы, но это не переносимый код, и цикл не контролируется - это плохой вариант и подойдет лишь для демо.

Добавлено через 38 секунд
Renji, надо наоборот
0
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
09.02.2018, 17:50 9
Цитата Сообщение от IronnMann Посмотреть сообщение
главном цикле обрабатывались определенные данные
Мужик, не парь людям мозги. Создай обычное приложение десктопное и выполняй свои вычисления в thread-e или еще как нибудь, сам написал что

Цитата Сообщение от IronnMann Посмотреть сообщение
вин32 форма должна быть пользовательским интерфейсом, отображать некоторые данные
И еще: что за вычисления такие ты собрался проводить секретные что ни строчки кода не выложил? Не плохо бы увидеть весь код.

А еще можешь посмотреть в сторону IPC http://www.boost.org/doc/libs/... ocess.html
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
09.02.2018, 17:55  [ТС] 10
outoftime, да они не секретные, я их просто не писал еще. хотел скелет программы набросать а потом уж и наполнять постепенно. Ну значит пойдем другим путём=)
0
3958 / 2504 / 420
Регистрация: 09.09.2017
Сообщений: 10,999
09.02.2018, 19:19 11
Тогда вариант с разделяемой памятью будет идеален. На запись она доступна только ядру. Оно меняет координаты и прочие свойства всех объектов. При этом через канал (stdin хотя бы, но можно и обычный pipe) принимает команды.
Оболочка использует ту же общую память только на чтение (чтобы не было коллизий, можно использовать mutex'ы, но можно и обойти это тройной буферизацией) и отображает на экране по своему оконному циклу. При нажатии кнопок и прочего, оболочка формирует команды для ядра и посылает ему через канал.
Тогда это реализуется на thread'ах.
.
Но есть вариант проще: вынести обработку оконных событий в отдельную функцию (для переносимости) и вызывать ее по основному игровому циклу с нужным тебе периодом. То есть не игровой цикл привязать к обработке окна а наоборот. Я так делал и оно вполне неплохо смотрелось.
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
09.02.2018, 19:44 12
Странно, а попробуй наоборот, пустить мейнлуп в потоке... Чет мне кажется в проблема в CDevice.
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
09.02.2018, 19:56  [ТС] 13
Всем спасибо нашел свою ошибку!
0
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
10.02.2018, 01:51 14
IronnMann, поделись кодом, интересно же.
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
12.02.2018, 00:10  [ТС] 15
outoftime, Вот тут человек уже решил подобную фиговину в своем движке, как раз мне подошло, я опираясь на этот код написал своё и работает как то)
Кликните здесь для просмотра всего текста

Хедер
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
/**
\author     Korotkov Andrey aka DRON
\date       12.04.2016 (c)Korotkov Andrey
 
This file is a part of DGLE project and is distributed
under the terms of the GNU Lesser General Public License.
See "DGLE.h" for more details.
*/
 
#pragma once
 
#include "Common.h"
 
class CConsoleWindow final : public IConsoleWindow
{
    static constexpr uint _sc_uiTmpBufferSize = 256;
    static constexpr uint _sc_uiMaxConsoleTxtLength = 30000;
 
    HINSTANCE _hInst;
    std::string _strOnCreate;
    int _iX, _iY, _iWidth, _iHeight;
    bool _bVisible;
    int _iPrevLineSize;
    bool _bToPrevLineActive;
    HWND _hWnd, _hMemo, _hEdit;
    HFONT _hFont;
    CRITICAL_SECTION _cs;
    HANDLE _hThreadHandle;
    DWORD _threadId;
    void *_pOldEditProc;
    
    CConsole *_pConsole;
 
    void (DGLE_API *_pConWindowEvent)(CConsole *pConsole, E_CONSOLE_WINDOW_EVENT eEventType, const char *pcCommand); 
 
    int WINAPI _WinMain(HINSTANCE hInstance);   
    void _Realign();
    
    static LRESULT CALLBACK _s_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static LRESULT CALLBACK _s_WndEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    static DWORD WINAPI _s_ThreadProc(LPVOID lpParameter);
 
public:
 
    CConsoleWindow();
 
    DGLE_RESULT InitWindow(bool bSeparateThread, void (DGLE_API *pConWindowEvent)(CConsole *pConsole, E_CONSOLE_WINDOW_EVENT eEventType, const char *pcCommand), CConsole *pConsole) override;
    DGLE_RESULT Visible(bool bVisible) override;
    DGLE_RESULT SetSizeAndPos(int iX, int iY, int iWidth, int iHeight) override;
    DGLE_RESULT GetSizeAndPos(int &iX, int &iY, int &iWidth, int &iHeight) override;
    DGLE_RESULT GetWindowHandle(TWindowHandle &tHandle) override;
    DGLE_RESULT GetThreadId(uint32 &ui32Id) override;
    DGLE_RESULT OutputTxt(const char *pcTxt, bool bToPrevLine) override;
    DGLE_RESULT GetEditTxt(char *pcTxt, uint uiBufferSize) override;
    DGLE_RESULT SetEditTxt(const char *pcTxt) override;
    DGLE_RESULT GetConsoleTxt(char *pcTxt, uint &uiBufferSize) override;
    DGLE_RESULT Clear() override;
    DGLE_RESULT ResetSizeAndPos() override;
    DGLE_RESULT EnterThreadSafeSection() override;
    DGLE_RESULT LeaveThreadSafeSection() override;
    DGLE_RESULT Free() override;
 
    IDGLE_BASE_IMPLEMENTATION(IConsoleWindow, INTERFACE_IMPL_END)
};
Сорц
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
/**
\author     Korotkov Andrey aka DRON
\date       19.04.2016 (c)Korotkov Andrey
 
This file is a part of DGLE project and is distributed
under the terms of the GNU Lesser General Public License.
See "DGLE.h" for more details.
*/
 
#include "Common.h"
#include "ConsoleWindow.h"
#include "..\..\..\..\build\windows\engine\resource.h"
 
using namespace std;
 
extern HMODULE hModule;
 
#define C_WND_X 20
#define C_WND_Y -10
#define C_WND_WIDTH  450
#define C_WND_HEIGHT 250
#define C_WND_MIN_WIDTH  300
#define C_WND_MIN_HEIGHT 115
#define C_WND_EDIT_HEIGHT 16
 
LOGFONT LF = {12, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, "Lucida Console"};
 
CConsoleWindow::CConsoleWindow():
_strOnCreate("DGLE Console created..."),
_iPrevLineSize(22),
_bToPrevLineActive(false),
_hWnd(), _hMemo(), _hEdit(),
_hInst(), _hThreadHandle(), _threadId(),
_pOldEditProc(), _bVisible(false),
_pConWindowEvent(), _pConsole()
{}
 
DGLE_RESULT CConsoleWindow::InitWindow(bool bSeparateThread, void (DGLE_API *pConWindowEvent)(CConsole *pConsole, E_CONSOLE_WINDOW_EVENT eEventType, const char *pcCommand), CConsole *pConsole)
{
    _pConWindowEvent = pConWindowEvent;
    _pConsole = pConsole;
 
    if (bSeparateThread)
    {
        InitializeCriticalSection(&_cs);
        _hThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_s_ThreadProc, (PVOID)this, 0, &_threadId);
    }
    
    if (!_hThreadHandle)
        _WinMain(hModule);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::Visible(bool bVisible)
{
    if (!bVisible)
        ShowWindow(_hWnd, SW_HIDE);
    else
    {
        if (_hWnd == NULL) 
        {
            _bVisible = true;
            return S_OK;
        }
        ShowWindow(_hWnd, SW_SHOWNA);
        SetForegroundWindow(_hWnd);
        RECT hwrc;
        GetWindowRect(_hWnd, &hwrc);
        SetCursorPos(hwrc.left + (hwrc.right - hwrc.left) / 2, hwrc.top + (hwrc.bottom - hwrc.top) / 2);
        SetFocus(_hEdit);
        UpdateWindow(_hWnd);
    }
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::SetSizeAndPos(int iX, int iY, int iWidth, int iHeight)
{
    _iX = iX;
    _iY = iY;
    _iWidth = iWidth;
    _iHeight = iHeight;
 
    MoveWindow(_hWnd, iX, iY, iWidth, iHeight, true);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::GetSizeAndPos(int &iX, int &iY, int &iWidth, int &iHeight)
{
    iX = _iX;
    iY = _iY;
    iWidth = _iWidth;
    iHeight = _iHeight;
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::GetWindowHandle(TWindowHandle &tHandle)
{
    tHandle = _hWnd;
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::GetThreadId(uint32 &ui32Id)
{
    ui32Id = _threadId;
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::OutputTxt(const char *pcTxt, bool bToPrevLine)
{
    int cur_l = GetWindowTextLength(_hMemo);
    
    if (cur_l + strlen(pcTxt) + 4 >= _sc_uiMaxConsoleTxtLength)
    {
        SetWindowText(_hMemo, "DGLE Console cleared...");
        cur_l = GetWindowTextLength(_hMemo);
    }
    
    if (_bToPrevLineActive && bToPrevLine) 
    {
        SendMessage(_hMemo, EM_SETSEL, cur_l - _iPrevLineSize, cur_l);
        SendMessage(_hMemo, EM_REPLACESEL, false, (LPARAM)pcTxt);
    }
    else
    {
        _bToPrevLineActive = bToPrevLine;
 
        if (_hThreadHandle && _hMemo == NULL)
            _strOnCreate += "\r\n"s + pcTxt;
        else
        {
            SendMessage(_hMemo, EM_SETSEL, cur_l, cur_l);
            SendMessage(_hMemo, EM_REPLACESEL, false, (LPARAM)("\r\n"s + pcTxt).c_str());
            SendMessage(_hMemo, EM_SCROLL, SB_BOTTOM, 0);
        }
    } 
 
    _iPrevLineSize = (int)strlen(pcTxt);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::GetEditTxt(char *pcTxt, uint uiBufferSize)
{
    GetWindowText(_hEdit, pcTxt, uiBufferSize);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::SetEditTxt(const char *pcTxt)
{
    SetWindowText(_hEdit, pcTxt);
    SendMessage(_hEdit, WM_KEYDOWN, 35 /*end*/, 0);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::GetConsoleTxt(char *pcTxt, uint &uiBufferSize)
{
    if (!pcTxt)
    {
        uiBufferSize = _sc_uiMaxConsoleTxtLength + 1;
        return S_OK;
    }
 
    return uiBufferSize - 1 == GetWindowText(_hMemo, pcTxt, uiBufferSize) ? S_FALSE : S_OK;
}
 
DGLE_RESULT CConsoleWindow::Clear()
{
    SetWindowText(_hMemo, "DGLE Console cleared...");
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::ResetSizeAndPos()
{
    uint dt_w, dt_h;
    GetDisplaySize(dt_w, dt_h);
 
    RECT rc_tb;
    GetWindowRect(FindWindow("Shell_TrayWnd", NULL), &rc_tb);
 
    _iWidth = C_WND_WIDTH;
    _iHeight = C_WND_HEIGHT;
 
    RECT rc = { 0, 0, C_WND_WIDTH, C_WND_HEIGHT };
    AdjustWindowRectEx(&rc, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX, false, WS_EX_TOOLWINDOW);
 
    _iX = (int)(C_WND_X + min(rc_tb.bottom - rc_tb.top, rc_tb.right - rc_tb.left));
    _iY = (int)(dt_h - (rc.bottom - rc.top) + C_WND_Y - min(rc_tb.bottom - rc_tb.top, rc_tb.right - rc_tb.left));
 
    MoveWindow(_hWnd, _iX, _iY, _iWidth, _iHeight, true);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::EnterThreadSafeSection()
{
    if (_hThreadHandle)
        EnterCriticalSection(&_cs);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::LeaveThreadSafeSection()
{
    if (_hThreadHandle)
        LeaveCriticalSection(&_cs);
 
    return S_OK;
}
 
DGLE_RESULT CConsoleWindow::Free()
{
    if (_hThreadHandle)
    {
        PostThreadMessage(_threadId, WM_EXIT, 0, 0);
 
        WaitForSingleObject(_hThreadHandle, INFINITE);
 
        CloseHandle(_hThreadHandle);
        DeleteCriticalSection(&_cs);
    }
 
    if (_hWnd && FALSE != DestroyWindow(_hWnd))
        UnregisterClass("DGLEConsoleClass", _hInst);
 
    delete this;
 
    return S_OK;
}
 
int WINAPI CConsoleWindow::_WinMain(HINSTANCE hInstance)    
{
    _hInst = hInstance;
 
    WNDCLASSEX wcex;
    wcex.cbSize         = sizeof(WNDCLASSEX); 
    wcex.style          = CS_HREDRAW | CS_VREDRAW ;
    wcex.lpfnWndProc    = (WNDPROC)CConsoleWindow::_s_WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = _hInst; 
    wcex.hIcon          = LoadIcon(hModule, MAKEINTRESOURCE(IDI_ICON1));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_GRAYTEXT);
    wcex.lpszMenuName   = NULL;
    wcex.lpszClassName  = "DGLEConsoleClass";
    wcex.hIconSm        = LoadIcon(hModule, MAKEINTRESOURCE(IDI_ICON1));
    
    if (FindAtom("DGLEConsoleClass") == NULL && !RegisterClassEx(&wcex))
    {
        MessageBox(NULL, "Failed to register console class!", "DGLE Console", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
        return E_FAIL;
    }
 
    _hWnd = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_TOPMOST, "DGLEConsoleClass", "DGLE Console", 
                            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEBOX,
                            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                            NULL, NULL, hInstance, NULL);
 
    if (!_hWnd)
    {
        MessageBox(NULL, "Failed to create console window!", "DGLE Console", MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
        return E_FAIL;
    }
 
    SetWindowLongPtr(_hWnd, GWLP_USERDATA, (LONG_PTR)this);
 
    _hMemo = CreateWindow(  "EDIT", "DGLE Console created...", 
                            WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | 
                            ES_MULTILINE | ES_READONLY, 
                            0, 0, 0, 0, _hWnd, 0, 0, NULL );
 
    if (_strOnCreate.size() != 0)
    {
        SetWindowText(_hMemo, _strOnCreate.c_str());
        _strOnCreate.clear();
    }
 
    _hFont = CreateFontIndirect(&LF);
    
    SendMessage(_hMemo, WM_SETFONT, (WPARAM)_hFont, MAKELPARAM(TRUE,0));
 
    _hEdit = CreateWindow(  "EDIT", "",
                            WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
                            0, 0, 0, 0, _hWnd, 0, 0, NULL);
    
    SetWindowLongPtr(_hEdit, GWLP_USERDATA, (LONG_PTR)this);
 
    _pOldEditProc = (void *)SetWindowLongPtr(_hEdit, GWLP_WNDPROC, (LONG_PTR)(WNDPROC)CConsoleWindow::_s_WndEditProc); 
 
    SendMessage(_hEdit, WM_SETFONT, (WPARAM)_hFont, MAKELPARAM(TRUE, 0));
    
    ResetSizeAndPos();
 
    if (_bVisible)
        ShowWindow(_hWnd, SW_SHOWNORMAL);
 
    return S_OK;
}
 
void CConsoleWindow::_Realign()
{
    RECT rect;
    GetClientRect(_hWnd, &rect);
    MoveWindow(_hMemo, 0, 0, rect.right, rect.bottom - C_WND_EDIT_HEIGHT, true);
    MoveWindow(_hEdit, 0, rect.bottom - C_WND_EDIT_HEIGHT, rect.right, C_WND_EDIT_HEIGHT, true);
}
 
LRESULT CALLBACK CConsoleWindow::_s_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    CConsoleWindow *this_ptr = (CConsoleWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
 
    switch (message) 
    {
    case WM_MOVE:
        this_ptr->_iX = LOWORD(lParam);
        this_ptr->_iY = HIWORD(lParam);
        break;
 
    case WM_SHOWWINDOW:
        this_ptr->_bVisible = (wParam == TRUE);
        SetFocus(this_ptr->_hEdit);
        break;
 
    case WM_CLOSE:
        ShowWindow(this_ptr->_hWnd, SW_HIDE );
        break;
 
    case WM_SIZE:
        this_ptr->_iWidth = LOWORD(lParam);
        this_ptr->_iHeight = HIWORD(lParam);
        this_ptr->_Realign();
        break;
 
    case WM_DESTROY:
        DeleteObject(this_ptr->_hFont);
        break;
 
    case WM_GETMINMAXINFO:
        POINT pt;
        pt.x = C_WND_MIN_WIDTH;
        pt.y = C_WND_MIN_HEIGHT;
        ((MINMAXINFO *)lParam)->ptMinTrackSize = pt;
        break;
 
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
 
    return 0;
 
}
 
LRESULT CALLBACK CConsoleWindow::_s_WndEditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    CConsoleWindow *this_ptr = (CConsoleWindow *)GetWindowLongPtr(GetParent(hWnd), GWLP_USERDATA);
    
    char tmp[_sc_uiTmpBufferSize];
 
    switch (message) 
    {
    case WM_KEYUP:
        switch (wParam)
        {
            case 192: //tilda
                this_ptr->Visible(false);
                SetWindowText(this_ptr->_hEdit, "");
                break;
 
            case 38: //up           
                this_ptr->_pConWindowEvent(this_ptr->_pConsole, CWE_PREVIOUS_COMMAND, "");
                break;
 
            case 40: //down             
                this_ptr->_pConWindowEvent(this_ptr->_pConsole, CWE_NEXT_COMMAND, "");
                break;
        }
        break;
 
    case WM_CHAR:
        if (wParam == 96 /*tilda*/)
            break;
 
        if (GetWindowTextLength(this_ptr->_hEdit) > 0)
        {
            if (wParam == 9 /*tab*/)
            {
                GetWindowText(this_ptr->_hEdit, tmp, _sc_uiTmpBufferSize);
                this_ptr->_pConWindowEvent(this_ptr->_pConsole, CWE_COMPLETE_COMMAND, tmp);
 
                break;
            }
            else
                if (wParam == 13 /*return*/)
                {
                    GetWindowText(this_ptr->_hEdit, tmp, _sc_uiTmpBufferSize);
                    SetWindowText(this_ptr->_hEdit, NULL);
                
                    this_ptr->_pConWindowEvent(this_ptr->_pConsole, CWE_EXECUTE_COMMAND, tmp);
                
                    break;
                }
        }
        goto callDefWndPros;
 
    case WM_KEYDOWN:
        if (wParam == 38 /*up*/ || wParam == 40 /*down*/)
            break;
        else
            goto callDefWndPros;
 
    default:
        goto callDefWndPros;
    }
 
    return 0;
 
callDefWndPros:
    return CallWindowProc((WNDPROC)this_ptr->_pOldEditProc, hWnd, message, wParam, lParam);
}
 
DWORD WINAPI CConsoleWindow::_s_ThreadProc(LPVOID lpParameter)
{
    CConsoleWindow *this_ptr = (CConsoleWindow *)lpParameter;
 
    if (this_ptr->_WinMain(GetModuleHandle(NULL)) != S_OK)
        return FALSE;
 
    MSG msg = {0};
 
    while (true)
        if (WaitMessage() && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            switch (msg.message)
            {
            case WM_EXIT:
                PostQuitMessage(msg.wParam);
                break;
            case WM_QUIT:
                if (FALSE != DestroyWindow(this_ptr->_hWnd))
                    UnregisterClass("DGLEConsoleClass", this_ptr->_hInst);
                this_ptr->_hWnd = NULL;
                return msg.wParam;
            default:
                TranslateMessage(&msg);
                DispatchMessage(&msg);
                break;
            }
        }
}


Добавлено через 3 минуты
ошибка в том, что многое из того кода не учёл, и потому и работало через одно место
0
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
12.02.2018, 08:45 16
Цитата Сообщение от IronnMann Посмотреть сообщение
Суть в том что мне нужно чтобы в основном (консольном приложении) в главном цикле обрабатывались определенные данные, а вин32 форма должна быть пользовательским интерфейсом
Я вот ни как суть этих танцев с бубном понять не могу, можете пояснить?
Что значит вычисления в консоли? Консоль - это user interface, зачем вам два интерфейса для работы с программой и графический и консольный?
0
3958 / 2504 / 420
Регистрация: 09.09.2017
Сообщений: 10,999
12.02.2018, 11:13 17
Ну как же. Графический для пользователя (его почему-то пугает черный экран с белыми буквами), консольный для админа (чтобы мог поправить что-то на сервере). Ну и разнесение логики и представления штука в любом случае полезная.
0
571 / 353 / 133
Регистрация: 15.09.2017
Сообщений: 1,239
12.02.2018, 12:15 18
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Графический для пользователя (его почему-то пугает черный экран с белыми буквами), консольный для админа (чтобы мог поправить что-то на сервере)
Я всегда считал, что этим должны заниматься отдельные программы, клиенты называются, есть консольные клиенты, есть графические, а есть сервер, ну это ИМХО конечно
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну и разнесение логики и представления штука в любом случае полезная.
А вот здесь поподробнее, при чем здесь разнесение логики и интерфейсы?
0
3958 / 2504 / 420
Регистрация: 09.09.2017
Сообщений: 10,999
12.02.2018, 12:38 19
Цитата Сообщение от Avaddon74 Посмотреть сообщение
Я всегда считал, что этим должны заниматься отдельные программы, клиенты называются, есть консольные клиенты, есть графические, а есть сервер, ну это ИМХО конечно
Абсолютно согласен. Собственно, примерно такой вариант я и предлагал ТСу.
Цитата Сообщение от Avaddon74 Посмотреть сообщение
А вот здесь поподробнее, при чем здесь разнесение логики и интерфейсы?
Я имел в виду именно то что вы написали: один или несколько клиентов, дергающие сервер скажем по сетевому протоколу или каналам (если на локальной машине). А родной консольный интерфейс для диалога с админом... ну, по крайней мере, разработчиком.
0
6 / 6 / 2
Регистрация: 21.05.2013
Сообщений: 47
13.02.2018, 14:28  [ТС] 20
А еще у меня вот такой вариант сработал
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <thread>
 
 
int main()  
{
    std::thread threadObj( (CDevice()) );
    while (true)
    {
        std::cout<<"Display From Main Thread "<<std::endl;
 
    }
      
    std::cout<<"Waiting For Thread to complete"<<std::endl;
    threadObj.join();
    std::cout<<"Exiting from Main Thread"<<std::endl;
    return 0;
}
чуток кода
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
void CDevice::operator()(){
 
_hInstance = GetModuleHandle(NULL);
    _wincl.hInstance = _hInstance;
    _wincl.lpszClassName = L"абв";
    _wincl.lpfnWndProc = _WindowProcedure;      /* This function is called by windows */
    _wincl.style = CS_DBLCLKS;                 
    _wincl.cbSize = sizeof (WNDCLASSEX);
 
    _wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    _wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    _wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    _wincl.lpszMenuName = NULL;                 
    _wincl.cbClsExtra = 0;                      
    _wincl.cbWndExtra = 0;                      
    /* Use Windows's default colour as the background of the window */
    _wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    if (!RegisterClassEx (&_wincl)) exit(1);
 
    _hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           L"Azure.Sky.Engine",         /* Classname */
           L"AZURE SKY ENGINE: Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           800,                 /* The programs width */
           600,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           _hInstance,           /* Program Instance handler */
           NULL );              /* No Window Creation data */
    ShowWindow (_hwnd, SW_SHOW);
    _WinMain(_hInstance);       }
0
13.02.2018, 14:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.02.2018, 14:28
Помогаю со студенческими работами здесь

Консольное приложение Win32 - ошибка c0000005
Visual Studio 2010 express Программа http://rghost.ru/53607442 Исходник основного файла ...

Как переделать форму в консольное приложение и получать параметры запуска
Ребята, очень нужна Ваша помощь! У меня есть ооочень большой проект на Делфи 10. В нём куча...

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

Как можно скомпилировать win32 приложение в win32 приложение без консоли с помощью g++?
Как можно скомпилировать win32 приложение в win32 приложение без консоли с помощью g++? Например по...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru