2013-08-10 2 views
0

Привет, мои коллеги из StackOverflow!Отменить нить правильно при нажатии кнопки закрытия диалогового окна

Я постараюсь быть кратким, так что я буду резать до точки:

Я работаю на Windows XP, в C++, с использованием чистого Win32, чтобы создать диалоговое окно.

В этом диалоговом окне есть некоторые элементы управления редактированием и кнопка ОК, которая активирует поток при нажатии.

Тема затем собирает текст из элементов управления редактирования и записывает их в документ MS Word, используя OLE Automation.

Все работает нормально, когда я нажимаю кнопку «ОК», и жду, пока поток не покажет заполненный документ Word.

Однако, когда я нажимаю кнопку «ОК», а затем закрываю диалоговое окно, а поток находится посреди работы, появляется пустой документ Word.

Для иллюстрации моей проблемы здесь некоторые фрагменты кода:

Это фрагмент кода для функции потока:

DWORD WINAPI TabelaSvihObjekata(LPVOID hWnd) // hWnd is handle of the Dialog box 
    { 

      // obtain dialogs window handle 

     HWND hwnd = (HWND)hWnd; 

     // Initialize COM for this thread... 

     CoInitialize(NULL); 

     // Get CLSID for our server... 

     CLSID clsid; 

     HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid); 

      // do other Automation stuff and clean afterwards 
    } 

В диалоговом окне, это фрагмент кода для обработчика кнопки:

case IDOK: 
    { 
     // create thread 

     DWORD threadID; 

     HANDLE threadHandle = CreateThread(NULL , 0 , 
          (LPTHREAD_START_ROUTINE)TabelaSvihObjekata , 
          (void*)hwnd , 0 , &threadID); 

     if(!threadHandle) 
     { 
      MessageBox(hwnd, L"Error", L"Error", MB_ICONERROR); 

      EndDialog(hwnd, IDCANCEL); 
     } 

     CloseHandle(threadHandle); 

    } 

И это проблемный обработчик:

case IDCANCEL: 

      EndDialog(hwnd, IDCANCEL); 

     break; 

Я нашел MSDN для подсказки и нашел только ExitThread в качестве решения, но я не знаю, как правильно его использовать, так как я неопытен с потоками.

Просматривая архив SO, я нашел несколько примеров на C#, где люди вводят логическую переменную и проверяют ее значение во время цикла, поэтому они могут определить, следует ли прервать поток или позволить ему работать. Был предложен другой способ, где нить помещается в отдельный процесс, а затем убивается.

Мой вопрос:

Что нужно добавить или изменить, поэтому, когда я закрыть диалоговое окно, приложение Слово закрывается вместе с разрушением нитей?

Если есть что-то еще, что я могу сделать, чтобы помочь, спросите, и я с удовольствием сделаю это.

Спасибо всем, кто пытается помочь.

+0

это может быть полезно: http: //www.codeproject.com/Articles/552/Using-Worker-Threads – bitwise

+0

Это дает мне несколько идей, но в основном это MFC. Мне очень трудно следовать в этот момент, так как я новичок в потоках, но я буду перечитывать его снова и снова, надеясь, что это поможет мне решить эту проблему. Большое вам спасибо за ответ! –

+0

основной целью, которую я хотел передать, было использование логической переменной, которая регулярно проверяется внутри рабочего потока. Если ваш поток main/gui должен прекратить работу, он должен установить логическое значение false, и ваш рабочий должен соответствующим образом отреагировать на следующую проверку. К сожалению, нет автоматического способа очистки после рабочего потока, поэтому, когда ваш рабочий thread считает, что (running == false), он должен закрыть ms-word, если он уже открыт, перед возвратом из функции потока. – bitwise

ответ

-2

Если вы используете WinApi, вы должны сделать threadhandle доступным другой частью кода. Затем, чтобы завершить поток, вы можете использовать ExitThread - это предпочтительный вариант с помощью MSDN. Я покажу вам, как вы можете использовать его:

DWORD threadID; 
HANDLE hthread; 
void TerminateYourThread() 
{ 
    DWORD exitCode; 
    if(GetExitCodeThread(hThread,&exitCode) != 0) // check if your thread is active 
    { 
    ExitThread(exitCode); // terminating thread 

    if(CloseHandle(hThread)) // closing handle 
    { 
     // 
    } 
    } 
} 

void CreateYourThread() 
{ 
    hThread = CreateThread(NULL , 0 , 
         (LPTHREAD_START_ROUTINE)TabelaSvihObjekata , 
         (void*)hwnd , 0 , &threadID); 
} 

Теперь, когда вы хотите прервать нить просто вызвать функцию TerminateYourThread. Он ждет, пока нить не будет закрыта. Это только предложение, а не окончательное решение, чтобы вы могли его реорганизовать в будущем.

+0

ОК, спасибо! Мне придется внимательно изучить этот фрагмент, поскольку я новичок в потоках. Мы будем «оставаться на связи», так как я сообщу о своем прогрессе как можно скорее. Еще раз спасибо! –

+0

Чтобы уточнить, ExitThread() выйдет из потока CALLING. Итак, зачем вызывать GetExitCodeThread()? Нить не нужно проверять, запущен ли он =/наоборот, вызов ExitThread из основного потока не будет иметь желаемого эффекта. – bitwise

Смежные вопросы