Вроде ... Я делал это прежде, чем использовать обмен сообщениями между Windows и потоком для их прослушивания. Помните, вы НЕ хотите изменять пользовательский интерфейс из какого-либо потока, а не из того, который его создал ...
Вот пример кода родительского окна, которое получает уведомление об изменении одной из дочерних окон Windows. Тот же принцип применяется при выполнении того, о чем вы говорите. Родительская Windows на самом деле не качает сообщения, пока ребенок открыт (да, но я забываю о том, что происходит у нее в голове) ... Прошло 10 лет с тех пор, как мне пришлось делать что-то подобное ... Но приведенный ниже код предназначен для родительского окна с сеткой и дочерним окном «Добавить / редактировать», которое открывается, и когда вы добавляете или редактируете элемент, оно обновляет родительскую GRID за окном модального редактирования. Это было разработано в MFC, так что вы представляете, что вам просто нужно добавить несколько переменных HWND к вызовам функций, чтобы заставить его работать под Win32, поскольку Win32 и MFC так взаимосвязаны.
Во-первых, в родительском окне я настраиваю поток:
DWORD WINAPI PopulateGridThread(void *ptr)
{
CMeterReadings *pThis = (CMeterReadings*)ptr;
pThis->hGridMutex = CreateMutex(NULL, FALSE, "Wims.MeterReadingGridUpdateMutex");
WaitForSingleObject(pThis->hGridMutex, 0);
if(WaitForSingleObject(pThis->hGridMutex, 0) != WAIT_OBJECT_0) {
return -2;
}
try {
if(pThis->m_Get.GetCheck() == FALSE)
{
if(pThis->m_Grid.IsEmpty())
{
CloseHandle(pThis->hGridMutex);
CloseHandle(pThis->hThreadHandle);
pThis->hThreadHandle = INVALID_HANDLE_VALUE;
pThis->m_DateFilter.EnableWindow(pThis->m_UseDate.GetCheck());
pThis->m_UseDate.EnableWindow(TRUE);
pThis->m_MeterFilter.EnableWindow(TRUE);
return -3;
}
}
pThis->hCursor = LoadCursor(NULL, IDC_APPSTARTING);
pThis->m_Get.SetCheck(FALSE);
pThis->m_DateFilter.EnableWindow(FALSE);
pThis->m_UseDate.EnableWindow(FALSE);
pThis->m_MeterFilter.EnableWindow(FALSE);
pThis->m_Grid.PushRow();
pThis->m_Grid.ResetContent();
bool bSuccess = false;
long nId = CCommonDialog::GetItemData(pThis->m_MeterFilter);
bool bUseDate = pThis->m_UseDate.GetCheck() == TRUE;
CProDate dtFilterDate;
pThis->m_DateFilter.GetTime(dtFilterDate);
if(nId == NULLCONSTANT || nId == LB_ERR)
{
bSuccess = pThis->m_EquipmentPtr.LoadFirstMeterReading(bUseDate ? CProDate::GetDateOnly(dtFilterDate) : CProDate::NullDate(), true);
}
else
{
bSuccess = pThis->m_EquipmentPtr.LoadFirstMeterReadingByMeterId(nId, bUseDate ? CProDate::GetDateOnly(dtFilterDate) : CProDate::NullDate());
}
if(pThis->m_EquipmentPtr.GetRecordsReturned() > 5000)
{
if(ThrowQuestion("This expansion could take a long time. Do you wish to continue?", pThis) == IDNO)
{
bSuccess = false;
}
}
pThis->m_Get.SetWindowText("&Stop");
if(bSuccess)
{
pThis->m_Grid.Redraw(false);
do
{
pThis->m_Grid.AddGridRow();
pThis->m_Grid.SetCellFormat(COLUMN_ADJUSTMENT, "Yes;No");
pThis->m_Grid.SetCheck(COLUMN_ADJUSTMENT, pThis->m_EquipmentPtr.AdjustmentIndc);
pThis->m_Grid.AddDatesToGrid(pThis->m_EquipmentPtr.ReadingDate, pThis->m_EquipmentPtr.EffectiveDate);
pThis->m_Grid.AddTextToGrid(COLUMN_METER, pThis->m_EquipmentPtr.MeterDesc);
/* Cut the rest of the fields, as they aren't important... */
}
while(pThis->m_EquipmentPtr.LoadNextMeterReading());
}
pThis->m_Grid.FinishGrid();
pThis->m_Grid.Redraw(true);
pThis->m_Grid.PopRow();
pThis->m_Grid.RedrawWindow();
}
CATCH_COM_ERROR("CMeterReadings::PopulateGridThread()")
CloseHandle(pThis->hGridMutex);
CloseHandle(pThis->hThreadHandle);
pThis->hThreadHandle = INVALID_HANDLE_VALUE;
pThis->m_DateFilter.EnableWindow(pThis->m_UseDate.GetCheck());
pThis->m_UseDate.EnableWindow(TRUE);
pThis->m_MeterFilter.EnableWindow(TRUE);
pThis->hCursor = LoadCursor(NULL, IDC_ARROW);
pThis->m_Get.SetWindowText("&Get");
return 1;
}
Затем в дочернем окне я отправлял сообщение родителю, когда пришло время обновляться. Я сделал это, создав поток, который просто отправлял сообщение, чтобы остальная часть диалогового окна продолжала функционировать ... (Или, в вашем случае, вы можете отправить сообщение непосредственно в Child HWND Windows, чтобы обновить его). .)
void _cdecl GridUpdateThread(void *ptr)
{
CEnterMeterReadingsDlg *pthis = (CEnterMeterReadingsDlg*)ptr;
if(pthis->NotifyParent())
{
pthis->NotifyParent()->SendMessage(CMeterReadings::GRID_UPDATE_MESSAGE, 0, 0);
}
}
Затем все это было приведено в действие, когда пользователь выбрал «СЛЕДУЮЩИЙ» в диалоговом окне вместо ОК или ОТМЕНА ...
_beginthread(GridUpdateThread, NULL, this);
Что ж, надеюсь, это поможет вам или даст вам некоторые идеи ...