Артем
sprata
Mодератор
Завкаф
Карма: +40/-5
Offline
Пол:
Сообщений: 1107
|
|
« : Июль 29, 2008, 11:37:40 » |
|
Предлагаю в этой теме задавать вопросы по сабжу. Но для начала скажу несколько слов тем, кто только планирует изучать WinAPI. Пересмотрев около десятка книг для начинающих, я выделил для себя только 3, действительно написанные на "русском" языке - П.Румянцев - Азбука программирования в Win32 API
- Ч.Петзолд - Программирования для Win95
- К.Финогенов - Win32. Основы программирования (2006)
Книга Румянцева по большей степени дублирует главы и примеры из книги Петзолда, но только более подробно и "разжевано". Требуется предварительное знание языка С, и основ ООП. Поэтому если Вы до этого писали лишь консольные приложения на С/С++ и хотите начать писать под Windows, то книга Румянцева или Петзолда безусловно для Вас. К.Финогенов основательно подошел к написанию книги, и начал с архитектуры процессоров и довольно подробным описанием используемых IDE. Также имеется целая глава, посвященная синтаксису стандартного языка С++. И только с 4-ой главы начинается изучение WinAPI. Поэтому, если с языком С/С++ Вы знакомы поверхностно, эта книга станет для Вас хорошим учителем. Полезные ссылки:
|
|
« Последнее редактирование: Октябрь 12, 2009, 08:59:22 от artem90 »
|
Записан
|
|
|
|
Магнетон Бора
ЖИЗНЬ - БАЯН
Cтудент
Карма: +1/-0
Offline
Пол:
Сообщений: 61
|
|
« Ответ #1 : Апрель 22, 2009, 02:37:45 » |
|
Доброе время суток, уважаемые форумчане ))) Есть такое дело... Делаю программу с помощью WinApi и у меня есть елемент управления ComboBox, а точнее их 2. Я их использую в диалоговом окне и прописываю в файле ресурсов. У меня в них хранятся ЧИСЛА вот вопрос как бы мне число оттуда вытащить и запомнить как ЧИСЛО, а не строку. Пробовал делать так: Вот небольшой фрагмент диалоговой функции, но тут какой-то баг и я никак не пойму в чем дело ((( case WM_COMMAND: { switch(LOWORD(wParam)) { case IDOK: nItem = SendMessage(hCombo1,CB_GETCURSEL,0,0); wx = atoi(SendMessage(hCombo1,CB_GETITEMDATA,nItem,0)); nItem = SendMessage(hCombo2,CB_GETCURSEL,0,0); wy = atoi(SendMessage(hCombo2,CB_GETITEMDATA,nItem,0)); case IDCANCEL: break; }; } break; Кто-нибудь может предложить вариант получения информации из этого элемента управления? З. Ы. Заранее благодарен
|
|
|
Записан
|
|
|
|
ZaQ
Бакалавр
Карма: +6/-1
Offline
Пол:
Сообщений: 128
|
|
« Ответ #2 : Апрель 27, 2009, 09:42:25 » |
|
А конвертнуть строку в число религия не позволяет???Чето я невнимательно читаю, пора спать . Ищи ошибку, читай МСДН.
|
|
|
Записан
|
|
|
|
TARAKAN
Tifon
Бакалавр
Карма: +0/-0
Offline
Пол:
Сообщений: 134
|
|
« Ответ #3 : Июнь 03, 2009, 09:15:20 » |
|
В программе создается поток, приостановка и продолжение работает. НО если попытаться завершить его, то заново запустить не получается ... На завершение выполняю potok1.stop=1; TerminateThread(potok1.hpotok,potok1.exitcode); На запуск пробовал делать potok1.hpotok=CreateThread(NULL,0,ThreadFunc_1,(PVOID)(&potok1),CREATE_SUSPENDED,&potok1.per_potok); potok1.hWndPot=hWndChild; potok1.stop=0; ResumeThread(potok1.hpotok); Не получается ... все равно не запускает поток ... точнее оно вроде как запускает его тк ошибок не выдает, но тот прямоугольник что должен двигаться вообще не появляется ... т е не прорисовывается ...
|
|
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
AlexXxandr
Гость
|
|
« Ответ #4 : Июнь 05, 2009, 05:09:40 » |
|
Нужно сделать так чтобы по WaitableTimer'у звучал сигнал Beep Вот как я делаю: VOID CALLBACK TimerAPCProc(LPVOID, DWORD, DWORD); HANDLE hWTimer; SYSTEMTIME st; FILETIME ftLocal, ftUTC; LARGE_INTEGER liUTC; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow){ //--------------------ТАЙМЕР-------------------------------------------------------------- // создаем таймер с автосбросом hWTimer = CreateWaitableTimer(NULL, FALSE, NULL); // узнаем текущую дату/время GetLocalTime(&st); st.wHour = 19; st.wMinute = 34; st.wSecond = 0; // преобразуем время из SYSTEMTIME в FILETIME SystemTimeToFileTime(&st, &ftLocal); // преобразуем местное время в UTC-время LocalFileTimeToFileTime(&ftLocal, &ftUTC); // преобразуем FILETIME в LARGE_INTEGER из-за // различий в выравнивании данных liUTC.LowPart = ftUTC.dwLowDateTime; liUTC.HighPart = ftUTC.dwHighDateTime; // устанавливаем таймер SetWaitableTimer(hWTimer, &liUTC, 24*60*60*1000, TimerAPCProc, NULL, FALSE); //--------------------------------------------------------------------------------------- } VOID CALLBACK TimerAPCProc(LPVOID, DWORD, DWORD){ Beep(1000,500); // выдается звуковой сигнал };
В StdAfx.h я прописал #define _WIN32_WINNT 0x0400 иначе не компилировалось. Проблема в том что если указать текущее время, то при запуске звуковой сигнал издается, а если указать только будущее время, то он не срабатывает, как мне кажется таймер просто не считает время. Помогите, что делать?
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #5 : Июнь 05, 2009, 11:23:09 » |
|
полные исходники - в ЗИП и приаттачь
|
|
|
Записан
|
|
|
|
AlexXxandr
Гость
|
|
« Ответ #6 : Июнь 06, 2009, 10:05:51 » |
|
Лаба компилица можете запускать, кусок кода с таймером выделен в ф-и винмэин.
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #7 : Июнь 07, 2009, 12:35:02 » |
|
итак, цитата "TimerAPCProc вызывается из того потока, который обратился к SetWaitableTimer в момент срабаты вания таймера, — но только если вызывающий поток находится в "тревожном" (aler table) состоянии, т. e. ожидает этого в вызове одной из функций SleepEx, WaitForSingle ObjectEx, WaitForMultipleObjectsEx,MsgWaitForMultipleObjectsEx или SignalObjectAndWait Если же поток этого не ожидает в любой из перечисленных функций, система не поставит в очередь АРС-функцию таймера. Тем самым система не даст АРС-очереди потока переполниться уведомлениями от таймера, которые могли бы впустую израсходовать колоссальный объем памяти. Если в момент срабатывания таймера Ваш поток находится в одной из перечис ленных ранее функций, система заставляет его вызвать процедуру обратного вызова"
|
|
|
Записан
|
|
|
|
AlexXxandr
Гость
|
|
« Ответ #8 : Июнь 07, 2009, 12:58:50 » |
|
Что то я не совсем понял, что мне поменять надо. Мне сеттаймер сделать в отдельный поток? Можно по проще объяснить плиз?
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #9 : Июнь 07, 2009, 01:09:43 » |
|
угу, можно создать в отдельном потоке, а потом вызвать в нем sleep
|
|
|
Записан
|
|
|
|
AlexXxandr
Гость
|
|
« Ответ #10 : Июнь 07, 2009, 01:41:25 » |
|
Создал 4ый поток при создании главного окна, поток запущенный, вот ф-я его обработки. Если раньше при установки текущей или прошедшей минуты оно срабатывало, теперь вообще не работает. DWORD WINAPI ThreadFunc_4(PVOID pvParam){ struct POTOK *p=(struct POTOK *)(pvParam); static HDC hDC=GetDC(p->hWndPot); hWTimer = CreateWaitableTimer(NULL, FALSE, NULL); GetLocalTime(&st); st.wHour = 13; st.wMinute = 39; st.wSecond = 00; SystemTimeToFileTime(&st, &ftLocal); LocalFileTimeToFileTime(&ftLocal, &ftUTC); liUTC.LowPart = ftUTC.dwLowDateTime; liUTC.HighPart = ftUTC.dwHighDateTime; while(!p->stop){ Sleep(1000); SetWaitableTimer(hWTimer, (LARGE_INTEGER *)&liUTC, 24*60*60*1000, TimerAPCProc, NULL, FALSE); } return(0); }
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #11 : Июнь 07, 2009, 01:51:45 » |
|
только если вызывающий поток находится в "тревожном" (aler table) состоянии, т. e. ожидает этого в вызове одной из функций SleepEx, WaitForSingle ObjectEx, WaitForMultipleObjectsEx,MsgWaitForMultipleObjectsEx или SignalObjectAndWait Если же поток этого не ожидает в любой из перечисленных функций, система не поставит в очередь АРС-функцию таймера. куда уж понятнее???
|
|
|
Записан
|
|
|
|
AlexXxandr
Гость
|
|
« Ответ #12 : Июнь 07, 2009, 02:03:14 » |
|
Так я итак делаю Sleep
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #13 : Июнь 07, 2009, 02:08:11 » |
|
Итак, читаем MSDN. Sleep Function
Suspends the execution of the current thread until the time-out interval elapses. To enter an alertable wait state, use the SleepEx function. понятненько? третий раз объяснил то, что написал.
|
|
|
Записан
|
|
|
|
AlexXxandr
Гость
|
|
« Ответ #14 : Июнь 07, 2009, 02:15:13 » |
|
Урааа!!!111 Я тупил т.к. я поставил SleepEx(1000,FALSE); и оно все так же не работало, но когда я поставил SleepEx(1000,TRUE); сразу заработало. Спасибо Вам большое!
|
|
|
Записан
|
|
|
|
tos
|
|
« Ответ #15 : Июнь 07, 2009, 02:20:04 » |
|
естественно, с false не работало. DWORD WINAPI SleepEx( __in DWORD dwMilliseconds, __in BOOL bAlertable ); ( Отправлено в: Июнь 07, 2009, 02:18:48 ) Не получается ... все равно не запускает поток ... а CloseHandle для дескриптора потока перед его пересозданием пробовал?
|
|
|
Записан
|
|
|
|
TARAKAN
Tifon
Бакалавр
Карма: +0/-0
Offline
Пол:
Сообщений: 134
|
|
« Ответ #16 : Июнь 07, 2009, 09:03:47 » |
|
а CloseHandle для дескриптора потока перед его пересозданием пробовал? Попоже попробую, сейчас проблема в другом... Вот пример который нам скинули Примеры программ по синхронизации потоков Критические разделы (секции) Пример использования критического раздела. Синхронизируется работа двух потоков при заполнении элементов массива значениями и выводе их на экран. CRITICAL_SECTION cs; DWORD a[5]; // Объявление глобального массива // Функция потока 1 DWORD WINAPI ThreadFunc1(PVOID pvParam) { int i; DWORD dwResult = 0, num=0; struct PARAM *p= (struct PARAM *) pvParam; while (!p->stop) { EnterCriticalSection(&cs); for ( i = 0; i < 5; i++ ) a[ i ] = num; LeaveCriticalSection(&cs); num++; } return(dwResult); } // Функция потока 2 DWORD WINAPI ThreadFunc2(PVOID pvParam) { int i; DWORD dwResult = 0; struct PARAM *p= (struct PARAM *) pvParam; while (!p->stop) { EnterCriticalSection(&cs); for ( i = 0; i < 5; i++ ) printf("%ld ", a[ i ]); printf("\n"); LeaveCriticalSection(&cs); } return(dwResult); } // --- Функция WinMain int APIENTRY WinMain(…) { // Создание объекта критический раздел InitializeCriticalSection(&cs); … // Удаление объекта критический раздел (при необходимости) DeleteCriticalSection(&cs); … } Моя программа прикреплена Проблема в том, что если запустить 2 или 3 поток, то другой уже не запуститься (2 или 3) А должны как я понимаю поочереди ... смотрю в пример и не понимаю в чем ошибка ... Пытался пример скомпилировать, он срабатывает 1 раз, т е выводит на экран 1 раз цифры, но потом вылетает ...
|
|
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
tos
|
|
« Ответ #17 : Июнь 07, 2009, 09:21:58 » |
|
начнём с того, что у тебя Sleep стоит внутри EnterCriticalSection - LeaveCriticalSection итог - другой поток вряд ли захватит критическую секцию
|
|
|
Записан
|
|
|
|
TARAKAN
Tifon
Бакалавр
Карма: +0/-0
Offline
Пол:
Сообщений: 134
|
|
« Ответ #18 : Июнь 07, 2009, 10:58:26 » |
|
Текстовая строка Перемещается сверху-вниз и наоборот с шагом 10 пикселей с интервалом 0,2 сек Прямоугольник с закругленными краями Перемещается по диагонали сверху-вниз и наоборот с шагом 40,30 пикселей с интервалом 0,5 сек
Если он (слип) так мешает, тогда как реализовать интервал между выполнением ? Всегда его использовал ... Просто даже сам пример 1 раз выполняет 1-й поток потом выполняет 2-й и программа вылетает ....
|
|
|
Записан
|
Студент: По моему легче использовать printf... EvilMax: Зато cout - это тру! = ))
|
|
|
tos
|
|
« Ответ #19 : Июнь 07, 2009, 11:01:41 » |
|
ну что ж вы такие невнимательные? Sleep выставь для начала из EnterCriticalSection - LeaveCriticalSection во внешний код
|
|
|
Записан
|
|
|
|
|