Проблемы с потоком MFC

Я нашел этот подход полезным. Таким образом, вам не нужен класс и окончательный

 btnInsert.addMouseListener(new MouseAdapter() {
        private Statement _statement;

        public MouseAdapter setStatement(Statement _stmnt)
        {
            _statement = _stmnt;
            return this;
        }
        @Override
        public void mouseDown(MouseEvent e) {
            String name = text.getText();
            String from = text_1.getText();
            String to = text_2.getText();
            String price = text_3.getText();

            String query = "INSERT INTO booking (name, fromst, tost, price) VALUES ('"+name+"', '"+from+"', '"+to+"', '"+price+"')";
            try {
                _statement.executeUpdate(query);
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }.setStatement(statement));
-1
задан IssamTP 13 July 2018 в 13:56
поделиться

2 ответа

Правильный способ - использовать AfxBeginThread или std::thread::detach. Вы можете использовать диалог в основном потоке пользовательского интерфейса.

В качестве альтернативы вы можете сделать это в одном потоке, предполагая, что ваша функция может быть прервана и сломана в разные части. Например, предположим, что у вас есть функция, которая занимает 3 секунды:

Sleep(3000);

Она может быть разбита на 30 частей и смоделирована как

for (int i = 0; i < 30; i++) 
    Sleep(100);

Вы можете обновить краску после каждого хода. Обратите внимание, что другие диалоговые сообщения должны игнорироваться, потому что это один поток, и вы можете делать только одно за раз. Вы должны отключить элементы управления, чтобы пользователь знал, что диалог занят. Пример:

void update_paint()
{
    MSG msg;
    while(PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE))
    {
        if(msg.message == WM_COMMAND && msg.wParam == IDCANCEL) { }//cancel reuested
        if(msg.message == WM_PAINT ||
            (msg.message >= WM_NCCALCSIZE && msg.message <= WM_NCACTIVATE) ||
            (msg.message >= WM_NCMOUSEMOVE && msg.message <= WM_NCMBUTTONDBLCLK))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

void CMyDialog::single_thread()
{
    MessageBox(L"start");
    //disable child controls to let user know the dialog is busy
    for(CWnd *p = GetWindow(GW_CHILD); p; p = p->GetWindow(GW_HWNDNEXT))
        p->EnableWindow(FALSE);

    for(int i = 0; i < 30; i++)
    {
        Sleep(100);
        update_paint();
    }

    //enable child controls
    for(CWnd *p = GetWindow(GW_CHILD); p; p = p->GetWindow(GW_HWNDNEXT))
        p->EnableWindow(TRUE);
    MessageBox(L"done");
}

Если функция не может быть прервана, необходимо запустить второй поток.

0
ответ дан Barmak Shemirani 17 August 2018 в 12:40
поделиться

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

Мое обходное решение состояло в том, чтобы вернуть управление в окно, чтобы оно могло потреблять сообщений:

// … thread stuff
for (auto nI = 0; nI < nCount; nI++)
{
     // Heavy computing
     nSleepStep = 5;
     nSleepTime = 200;
     while (nSleepTime > nSleepStep)
     {
          while(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
          {
             switch( msg.message ) 
             { 
             case WM_TIMER : 
             case WM_PAINT :
               TranslateMessage( &msg );
               DispatchMessage( &msg );
               break;
             }
         }
         std::this_thread::sleep_for(std::chrono::milliseconds(nSleepStep));
         nSleepTime -= nSleepStep;
     }
}
0
ответ дан IssamTP 17 August 2018 в 12:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: