Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
1

Как сделать, чтоб окно одновременно принимало сообщения и выполнялась какая-нибудь ф-ция

05.01.2011, 14:27. Показов 2891. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Опыт работы с "окнами" совсем небольшой (примеры из книг), вот решил сам попробовать. Сначала была консольная прога, все работало, решил прикрутить ее к окну Windows, написал маленькое окошко с кнопками "начать", "пауза" и "выход", и сталкнулся с такой проблемой - при нажатии кнопки "начать" запускается ф-ция (которая была главной в консольной проге) и пока эта ф-ция работает (1-2 минуты), окно не принимает сообщения, жму на "пауза" и ничего, при чем если понажимать на кнопки "пауза" и "выход", то после звершения этой ф-ции окно подвисает. Потом сделал так, через каждую строчку кода в этой ф-ции (которая 1-2 мин. работает) вставил такие строки:
C++
1
2
GetMessage(&Msg,NULL,0,0);
DispatchMessage (&Msg) ;
чтоб окно постоянно обрабатывало сообщения, но во первых - это лютый быдлокод, во вторых все равно глючит.
Вопрос - как решить подобную проблему? Желательно без второго потока)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.01.2011, 14:27
Ответы с готовыми решениями:

как сделать чтоб функция выполнялась пока зажата ЛКМ?
Есть макрос наподобие этого: mouse_event((0x0001), -1, 3, 0, 0); Sleep(11);...

как сделать чтоб команда выполнялась через некоторое время?
все в заголовке:)

Как сделать,чтоб после выполнения программа выполнялась заново и считывала значения уже с другого файла
#include "stdafx.h" #include "algorithm" // для min, max #include "iostream" #include...

Как выставить правило валидации,чтоб принимало число только с точкой?
Нужно прописать правило валидации чтоб принимало число только с точкой. Например чтоб принимало...

20
33 / 33 / 2
Регистрация: 24.09.2010
Сообщений: 140
05.01.2011, 15:39 2
Обычно в цикл функции которая долго работает вставляется типо
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
}
ещё посмотри Examining a Message Queue
1
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 15:47  [ТС] 3
Я что-то похожее сделал, понавставлял:
C++
1
2
3
4
if(PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE)){
    GetMessage(&Msg,NULL,0,0);
    DispatchMessage (&Msg) ;
    }
Попробую как ты показал, так за раз больше сообщений удалится из очереди, меньше вероятность подвисания, как мне кажется.

Цитата Сообщение от Nwq Посмотреть сообщение
ещё посмотри Examining a Message Queue
С английским совсем туго( Поищу что-нибудь по-русски на эту тему.
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.01.2011, 15:52 4
Kastaneda, при долгих вычисления, которые могут прервать поток сообщений GUI, обычно создают новый поток. Я думаю с этим будет меньше проблем.
0
Заблокирован
05.01.2011, 16:01 5
попробуйте вставить в цикл
C#
1
Application.DoEvents();
0
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 16:09  [ТС] 6
SSTREGG, да вот проблема в том, что я этого ни когда не пробовал, похоже придется.
Dzhej-Dzhej, сейчас почитаю, что это такое)

Добавлено через 23 секунды
Nwq, да, глюков меньше стало)

Добавлено через 6 минут
Dzhej-Dzhej, похоже это из области "программирования мышкой", на WinAPI такого нет. (если верить гуглу))
0
Заблокирован
05.01.2011, 16:14 7
Kastaneda, извиняюсь, не заметил, что С++
(функция для .net)
0
Kastaneda
05.01.2011, 16:16  [ТС]
  #8

Не по теме:

Цитата Сообщение от Dzhej-Dzhej Посмотреть сообщение
Kastaneda, извиняюсь, не заметил, что С++
Да это я не сказал, что на С++, забыл))

0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.01.2011, 16:20 9
Kastaneda, да там разбираться даже не надо функция CreateThread:
C++
1
2
3
4
5
6
7
8
9
10
DWORD WINAPI        ThreadProc(LPVOID);
...
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); /* Вызывай там где раньше выполнялось действие.
Лучше конечно прочитать, за что отвечает каждый параметр, и обрабатывать возможные неблагоприятные последствия */
...
DWORD WINAPI ThreadProc(LPVOID param)
{
    // Здесь выполнение времязатратного действия
    return 0;
}
В реальной ситуации надо только синхронизацию немного продумать.
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.01.2011, 16:24 10
Цитата Сообщение от Kastaneda Посмотреть сообщение
Желательно без второго потока)
Присоединяюсь к мнению, что проще работать через поток. При подходе, описанном в первом посте, программа выполняет дополнительные телодвижения, из-за которых всё-равно будет визуальное подлагивание гуя (во всяком случае, у меня было именно так), да и не всегда понятно, в каких местах надо вставлять такой код, чтобы он исполнялся с более-менее равномерными интервалами. А если создать поток, то весь геморрой ляжет на ОС (которая с этим справится гораздо лучше). Правда на программиста возлагается другой геморрой, связанный с синхронизацией. После исследований методом тыка я остановился на варианте именно с потоками. Правда это было в Borland'овском VCL, а не WinAPI, но принципиальной разницы нет. Геморрой заключался только в том, что надо разобраться с предметом и написать простенькую библиотеку поддержки
0
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 16:26  [ТС] 11
SSTREGG, наверно придеться. А что вы подразумеваете под синхронизацией? Я с потоками вообще не знаком.
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
05.01.2011, 16:37 12
Цитата Сообщение от Kastaneda Посмотреть сообщение
А что вы подразумеваете под синхронизацией?
Если у Вас в том методе использовались какие-либо данные, которые могут быть использованы в нескольких местах (методах, потоках) одновременно, то обычно для таких данных использую синхронизацию, дабы избежать беспорядочного обращения к этим данным, и всё делать синхронно (совместно) но при этом не нарушая порядка.

Для этой цели вполне могут подойди критические секции [MSDN]. К тому же вот [MSDN] описание возможных синхронизаций потоков.
1
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 16:58  [ТС] 13
Буду разбираться)
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.01.2011, 17:48 14
Ещё тут была долгая бодяга с синхронизацией
Вопрос по работе WaitForSingleObject
1
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 18:35  [ТС] 15
На сколько я понял, если у меня созданный поток будет работать с одной глобальной переменной (bool PAUSE), то мне ни какая синхронизация не нужна. Созданный поток будет только проверять значение переменно, менять ее он не будет.
И еще вопрос, когда в ф-цию главного окна (оно же единственное) будет послано сообщение WM_DESTROY, вызовется PostQuitMessage(0), я так понимаю, что при этом закроются все потоки, связанные с процессом, т.е. самостоятельно мне созданный поток зарывать не надо?

Добавлено через 24 минуты
А может кто-нибудь подскажет, как поток остановить, а потом заново (а не с места остановки) начать?
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.01.2011, 19:07 16
Цитата Сообщение от Kastaneda Посмотреть сообщение
На сколько я понял, если у меня созданный поток будет работать с одной глобальной переменной (bool PAUSE), то мне ни какая синхронизация не нужна. Созданный поток будет только проверять значение переменно, менять ее он не будет.
Теоретически да. Но если, грубо говоря, проверка идёт в цикле типа "while (var) { ... }", а тело цикла не содержит операций вызова, то переменную var надо пометить признаком volatile, чтобы компилятор знал, что в данном случае есть "невидимое для компилятора" средство модификации переменной, и не делал оптимизаций над ней

Цитата Сообщение от Kastaneda Посмотреть сообщение
И еще вопрос, когда в ф-цию главного окна (оно же единственное) будет послано сообщение WM_DESTROY, вызовется PostQuitMessage(0), я так понимаю, что при этом закроются все потоки, связанные с процессом, т.е. самостоятельно мне созданный поток зарывать не надо?
Посмотри Прибить программу, находясь в потоке
Там полезные ссылки

Цитата Сообщение от Kastaneda Посмотреть сообщение
А может кто-нибудь подскажет, как поток остановить, а потом заново (а не с места остановки) начать?
Мне кажется, что такого средства нет. Потому как нужно убить поток и запустить его заново. Это задача пользовательского уровня и навряд ли ОС будет какие-то интерфейсы для этого предоставлять
1
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 20:40  [ТС] 17
Скажите, корректно ли будет сделать так:
C++
1
2
3
4
5
6
7
DWORD WINAPI ThreadProc(LPVOID){
   while(true){
      if(!PAUSE)
         MyFunc();
   }
   return 0;
}
а когда плученно сообщение WM_DESTROY от главного окна, то вызывается такая ф-ция
C++
1
2
3
4
5
6
7
void OnDestroy(HWND,HANDLE T){//Т - это хендл потока
    DWORD ExitCode;
    GetExitCodeThread(T,&ExitCode);
    ExitThread(ExitCode);
    PostQuitMessage(0);
    //exit(0);
}
Завершится ли так созданный поток, ведь там вызов ф-ции в вечном цикле?
0
Evg
Эксперт CАвтор FAQ
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.01.2011, 20:49 18
Если OnDestroy предполагается выполнять в потоке, то вроде бы как нет. Сообщение - это всё-таки не сигнал. Чтобы его обработать, поток должен сделать некие телодвижения (залезть в очередь сообщений). Из главного процесса поток можно просто убить (или тебе важно, чтобы поток знал, что его убивают?)
0
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2011, 21:11  [ТС] 19
Если OnDestroy предполагается выполнять в потоке
Нет, не в потоке. OnDestroy вызывается из оконной процедуры главного окна.
(или тебе важно, чтобы поток знал, что его убивают?)
Нет, не важно. Попробовал сделать, как показал выше, окно закрывается (т.е. OnDestroy вызывается), а поток продолжает работать. А нужно,чтоб при закрытии окна (т.е. программы), поток убивался. Не могу сделать(

Добавлено через 3 минуты
Проблему решил, вместо:
C++
1
ExitThread(ExitCode);
нужно:
C++
1
TerminateThread(T,ExitCode);
0
33 / 33 / 2
Регистрация: 24.09.2010
Сообщений: 140
06.01.2011, 00:34 20
Перед выходом из программы нужно дождаться завершения потока:
hThread = CreateThread(...);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
0
06.01.2011, 00:34
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.01.2011, 00:34
Помогаю со студенческими работами здесь

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Что такое хорошо и что такое плохо, вид сбоку. Индивид и общество - грань не нарушения.
Hrethgir 18.01.2025
В моей личной жизни и времени, я рассуждаю категорией "хуже-лучше", в том плане, когда меня спросили например - "а зачем ты делаешь свой процессор?", то я ответил - "чтобы сделать свою жизнь лучше". . .
Передача по ссылке или по значению в Java?
InfoMaster 18.01.2025
В мире программирования на Java одним из ключевых аспектов, требующих глубокого понимания, является механизм передачи параметров в методы. Этот фундаментальный концепт часто становится источником. . .
Тернарный условный оператор в Python
InfoMaster 18.01.2025
В мире программирования существует множество инструментов и конструкций, позволяющих создавать эффективный и лаконичный код. Одним из таких инструментов является тернарный условный оператор, который. . .
Как удалить неотслеживаемые файлы из рабочего дерева Git
InfoMaster 18.01.2025
В процессе разработки программного обеспечения с использованием системы контроля версий Git часто возникает необходимость в управлении неотслеживаемыми файлами. Неотслеживаемые файлы (untracked. . .
Что делает код if __name__ == "__main__": в Python
InfoMaster 18.01.2025
В мире программирования на Python существует множество важных концепций, и одной из наиболее интересных является конструкция if __name__ == "__main__". Эта специальная конструкция играет ключевую. . .
Как заставить Git забыть об отслеживаемом файле, добавленном в .gitignore
InfoMaster 18.01.2025
В мире разработки программного обеспечения система контроля версий Git стала неотъемлемой частью рабочего процесса, позволяя эффективно отслеживать изменения в коде и управлять ими. Однако. . .
Что означает use strict в JavaScript и для чего используется
InfoMaster 18.01.2025
В мире современной веб-разработки JavaScript играет ключевую роль как один из основных языков программирования. По мере его эволюции возникла необходимость в механизмах, которые помогли бы. . .
Как работать со скрытыми (hidden) элементами в jQuery
InfoMaster 18.01.2025
В современной веб-разработке управление видимостью элементов на странице является одним из ключевых аспектов создания интерактивных пользовательских интерфейсов. jQuery предоставляет мощный набор. . .
Как переключаться между ветками (Branch) с помощью checkout в Git
InfoMaster 18.01.2025
Ветки в Git являются одной из ключевых концепций для управления версионностью кода, позволяя разработчикам эффективно работать в команде и параллельно развивать программные проекты. Каждый новый. . .
Что такое стек и куча, чем они отличаются и где находятся
InfoMaster 18.01.2025
Понимание основных концепций памяти в программировании В мире современного программирования эффективное управление памятью играет ключевую роль в создании производительных и надежных приложений. . . .
Как использовать комментарии в JSON
InfoMaster 18.01.2025
JSON (JavaScript Object Notation) представляет собой легкий и широко используемый формат обмена данными, который стал стандартом де-факто для веб-приложений и программных интерфейсов. При работе с. . .
Как заставить git pull перезаписать локальные файлы в Git
InfoMaster 18.01.2025
Проблема перезаписи локальных файлов в Git При работе с системой контроля версий Git разработчики часто сталкиваются с ситуацией, когда необходимо синхронизировать локальный репозиторий с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru