Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Программирование с использованием WinAPI

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

Открыть новую тему     Написать ответ в эту тему

akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

а вообще мне постановка своего обработчика и проверка в цикле счёта флага больше нравится, чем постоянный опрос клавы...

Всего записей: 24056 | Зарегистр. 06-12-2002 | Отправлено: 02:36 25-12-2020
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Можно и c Ctrl-F12

Код:
#include <windows.h>
#include <stdio.h>
 
int g_stop;
 
DWORD WINAPI ThreadProc(void* parm)
{
    for(;; Sleep(10))
        if(0x8000 & GetKeyState(VK_CONTROL) && 0x8000 & GetKeyState(VK_F12))
            g_stop = 1;
    return 0;
}
 
int main()
{
    CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL));
    
    for( ; !g_stop; )
        printf("q");
 
    printf("\nexiting on ctrl-F12\n");
}
 

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 13:00 25-12-2020
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ne_viens
 
выглядит клёво, да...
 
а что ещё делает строчка
Код:
CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL));
кроме создания и постановки обработчика?
 
и как за собой буфер почистить, а то после отрабоки этой твоей проги (под ФАРом)
вызывается "сорт моде" окно (ктрл-Ф12)?  :)

Всего записей: 24056 | Зарегистр. 06-12-2002 | Отправлено: 13:46 25-12-2020
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
почистился :)
 
в начале:
 
HANDLE std_input_handle = GetStdHandle(STD_INPUT_HANDLE);
 
и по завершению:
 
FlushConsoleInputBuffer(std_input_handle);

Всего записей: 24056 | Зарегистр. 06-12-2002 | Отправлено: 16:40 25-12-2020
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
...а что ещё делает строчка
Код:
CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL));
кроме создания и постановки обработчика?  

...
 
Создаёт новый замороченный поток и закрывает хендл к нему.
В потоке проверяется нажатие клавиш, и при их нажатии устанавливается гоп_стоп.

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 18:30 26-12-2020
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ne_viens
 
короче, всё работает, устанавливается, нажимается, ловится и чистится,
спасибо...
 

Цитата:
устанавливается гоп_стоп
:)
 
нон-стоп...

Всего записей: 24056 | Зарегистр. 06-12-2002 | Отправлено: 18:41 26-12-2020
V0lt



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вопрос по параметру lfHeight структуры LOGFONTW, который может быть как положительным, так и отрицательным

Цитата:
> 0     The font mapper transforms this value into device units and matches it against the cell height of the available fonts.
 
< 0     The font mapper transforms this value into device units and matches its absolute value against the character height of the available fonts.

В одном из переводов на русский это звучит так:

Цитата:
> 0     Механизм отображения логического шрифта в физический преобразует эту величину в единицы измерения устройства (пиксели) и приводит в его соответствие, сверяя с высотой ячейки доступных шрифтов.
 
< 0     Механизм отображения логического шрифта в физический преобразует эту величину в единицы измерения устройства (пиксели) и приводит в соответствие его абсолютную величину, сверяя с высотой символов доступных шрифтов.

Что это значит на человеческом?
 
И как правильно создать шрифт высотой 25 пикселей при масштабе дисплея 100%?
 
Поясню почему возник вопрос.
Высчитываю размер шрифта по формуле из статьи

Код:
lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

подставляю значения
lfHeight = -MulDiv(25, 96, 72) = -(25 * 96 / 72) = -33
Вывожу текст с помощью CDC::DrawTextEx

Код:
MemDC.DrawText(text, &rect, DT_RIGHT | DT_BOTTOM | DT_SINGLELINE | DT_NOPREFIX);

В результате текст не влезает в прямоугольник высотой 25 пикселей.

Всего записей: 10456 | Зарегистр. 05-02-2003 | Отправлено: 20:48 25-02-2021
bomzz

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
никто не знает как надо работать с консольным потоком превышающим размер консольного буфера?
cmd с потоками превыщающими размер буфера работают не вызывая переполнение буфера.
или хотя бы предположение куда копать, как такая очередь организуется
 

Всего записей: 3412 | Зарегистр. 29-03-2016 | Отправлено: 04:59 01-07-2021 | Исправлено: bomzz, 05:15 01-07-2021
V0lt



Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
VSPipe пишет большие объемы данных в stdout.
Смотрите и разбирайтесь сами.

Всего записей: 10456 | Зарегистр. 05-02-2003 | Отправлено: 05:40 01-07-2021
bomzz

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
V0lt
мне вообще то надо принять поток без переполнения, передать не проблема и передает cmd, но код просмотрю спасибо
 
Добавлено:
код использует стороннюю библиотеку
 
Добавлено:
гуглить надо было по слову pipe а не stream.
это по русски потоки и труба, а по глицки только pipe

Всего записей: 3412 | Зарегистр. 29-03-2016 | Отправлено: 06:34 01-07-2021 | Исправлено: bomzz, 06:58 01-07-2021
tiun

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Есть у стилей классов окон Windows флаг CS_SAVEBITS. Согласно документации, при выводе такого окна на экран Windows запоминает накрытую им часть экрана в виде картинки, а при убирании окна не посылает нижележащим окнам сообщение WM_PAINT, а просто восстанавливает запомненную картинку.
 
Проверяю:
Написал примитивнейшую тестовую программу, в которой выставлено CS_HREDRAW + CS_VREDRAW + CS_SAVEBITS, и которая единственное что делает - это выводит в центре своего окна и в его заголовке счётчик пришедших WM_PAINT. Запускаю эту программу два раза, одно из окон сильно уменьшаю и накрываю им счётчик в центре второго окна, после чего, щелкая мышкой по Панели задач, маленькое окно сворачиваю-восстанавливаю, сворачиваю-восстанавливаю, сворачиваю-восстанавливаю... И обнаруживаю, что после каждого сворачивания счётчик у большого окна увеличивается на 1. То есть, сообщение WM_PAINT этому окну приходит! Почему?
 
(Для полноты картины: если маленькое окно не сворачивать, а просто закрыть всю программу (хоть крестиком, хоть через Панель задач), то счётчик тоже увеличивается.)

Всего записей: 87 | Зарегистр. 02-11-2007 | Отправлено: 13:18 26-07-2021 | Исправлено: tiun, 14:43 26-07-2021
Garrett

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
tiun
Тут подробно объясняется почему так просиходит и для каких частей окна стоит применять этот стиль - https://devblogs.microsoft.com/oldnewthing/20060428-00/?p=31373

Всего записей: 2730 | Зарегистр. 16-10-2003 | Отправлено: 16:04 26-07-2021
tiun

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Garrett
Я читал эту статью. В ней разъясняется, почему сохранённая картинка может оказаться бесполезной и потребуется перерисовка. Мой эксперимент как раз и был поставлен учётом изложенного в статье: большое окно первой программы, над которым лежит только маленькое окно второй программы. В большом окне ничего не происходит, пока не придёт WM_PAINT, а маленькое окно никуда не двигается. То есть, смоделированы идеальные условия, но всё равно при закрытии маленького окна в большое приходит команда перерисовки.
 
И да, в настройках системы все виды анимации окон и меню отключены, так что даже в ту сторону думать нечего.
 
---
А-а, кажется, я понял, где может быть прокол в моём эксперименте: после создания второго окна нельзя ни двигать его, ни размер менять. Сейчас проверю.
 
Нет, не помогло: максимизировал окно первой программы, запустил вторую и, ничего больше с её окном не делая, начал через панель задач его сворачивать-разворачивать. По-прежнему приходят в первую программу WM_PAINT.

Всего записей: 87 | Зарегистр. 02-11-2007 | Отправлено: 19:09 26-07-2021 | Исправлено: tiun, 19:32 26-07-2021
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Нет, не помогло: максимизировал окно первой программы, запустил вторую и, ничего больше с её окном не делая, начал через панель задач его сворачивать-разворачивать. По-прежнему приходят в первую программу WM_PAINT.

Если мне память не изменяет, то свернуть окно - это переместить его за границы экрана. Поэтому может прилетать сообщение о перемещении.  
Попробуйте не сворачивать разворачивать, а по хэндлу окна слать WM_HIDE, WM_SHOW (но тоже не уверен).

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 10:22 27-07-2021
tiun

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Если мне память не изменяет, то свернуть окно - это переместить его за границы экрана. Поэтому может прилетать сообщение о перемещении.

Да, дело именно в этом. При сворачивании/разворачивании окна ему приходят несколько сообщений, в том числе WM_MOVE и WM_SIZE. А любое из них делает запомненную картинку недействительной.

Цитата:
Попробуйте не сворачивать разворачивать, а по хэндлу окна слать WM_HIDE, WM_SHOW (но тоже не уверен).

Уже нет смысла. Идея, в которой я хотел применить флаг CS_SAVEBITS, изначально корявая. А вчера я нашёл поистине волшебное решение своей задачи (добраться до области экрана, лежащей под окном моей программы). Совершенно случайно обнаружил. Из официальной документации никогда бы не догадался.

Всего записей: 87 | Зарегистр. 02-11-2007 | Отправлено: 17:25 27-07-2021 | Исправлено: tiun, 17:30 27-07-2021
serhio61

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Моё почтение!
По потокам просветите?
 
Хочется приостановить\восстановить поток.
На первый взгляд вроде всё просто CreateThread - SuspendThread - ResumeThread
 
Да вот чтой-то лыжи не едут.

Код:
 
HWND hwndLBL_COUNT,hwndSUSP,hwndRESUME;//Глобалки текст. метки и кнопок на диалоге
HANDLE hThr;//Это предмет вопроса
 
DWORD WINAPI ThrFunc(LPVOID data)// Функция потока
{
  char buf[5];
  for (int x=0;x<1000;x++)
    {
        Sleep(10);
        itoa(x,buf,10);
        SetWindowText(hwndLBL_COUNT,buf);
    }
    MessageBox(0,"Конец","КОНЕЕЕЦ!",MB_OKCANCEL);
  return 0;
}
...................
//Действия по кнопкам на диалоге
case IDOK:
    {
            hThr=CreateThread(NULL,0,ThrFunc,NULL,0,NULL);
        EnableWindow(hwndSUSP,TRUE);
    }
case IDSUSPEND:
    {
            SuspendThread(hThr);
        EnableWindow(hwndSUSP,FALSE);
        EnableWindow(hwndRESUME,TRUE);
    }
case IDRESUME:
    {
        ResumeThread(hThr);
        EnableWindow(hwndRESUME,FALSE);
        EnableWindow(hwndSUSP,TRUE);
        }
..........................................
        CloseHandle(hThr);//При закрытии диалога
 

Хочется-то малого...
По IDOK - запустить - этот шаг успешен, на лейбле счётчик крутится
По IDSUSPEND - остановить, вот прям чтобы счётчик встал - задница как раз здесь, окно диалога просто тихо закрывается
По IDRESUME - продолжить отсчёт счётчика...........окна диалога нет, жаловаться не на что
 
Всё не так просто?

Всего записей: 105 | Зарегистр. 10-04-2008 | Отправлено: 22:54 30-01-2022
Prober

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
serhio61
Цитата:
На первый взгляд вроде всё просто CreateThread - SuspendThread - ResumeThread

Так и есть, ничего сложного.
 
Для точного диагноза нужен весь код. Обратите внимание:
1. case обычно должны break-ами заканчиваться.
2. Какие значения у констант IDxxx, не пересекаются ли с системными.
3. Что возвращает диалоговая функция и в каких случаях.

Всего записей: 680 | Зарегистр. 01-11-2006 | Отправлено: 08:09 31-01-2022
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
И eщё SuspendThread(), ResumeThread() не предназначена для синхронизации потоков в обычном коде.
Для этого существует
 

Код:
 
CRITICAL_SECTION g_crit;
HANDLE g_hEvent;
 
DWORD WINAPI ThrFunc(LPVOID data)
{
...
    WaitForSingleObject(g_hEvent, INFINITE);
    EnterCriticalSection(&g_crit);
    SetWindowText(hwndLBL_COUNT,buf);
    LeaveCriticalSection(&g_crit);
...
}
 
 
    case IDSUSPEND:
        ResetEvent(g_hEvent);
...
    case IDRESUME:
        SetEvent(g_hEvent);
...
 
 
main()
{
    InitializeCriticalSection(&g_crit);
    g_hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
...
 
 

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 11:17 31-01-2022
serhio61

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Prober
А слона-то я и не приметил... :

Цитата:
1. case обычно должны break-ами заканчиваться.

 
Крутится - останавливается - опять крутится...
 
Однако как навык уходит. Больше 15 лет назад написана последняя строчка...
Открыл старые исходники и ОФИГЕЛ. Всё чужое... Потихоньку всплывает, конечно.
Потоки ещё тогда хотелось покрутить...

 
ne_viens
О! Совсем хорошо!
Значит в ThrFunc проверяется состояние события и, если взведено - проходим итерацию цикла, нет - курим.
 
Благодарности!
 
Добавлено:
Вдогонку...
 
Массив, объявленный и инициализированный как:

Код:
 
int *ARR;
int len=GetОткудаНадо();
ARR=(int*) malloc(len  * sizeof(int));
ARR[0]=1;
...
ARR[len-1]=77777;
 

нормально передать в ThrFunc как hThr=CreateThread(NULL,0,ThrFunc(&ARR),NULL,0,NULL); ?

Всего записей: 105 | Зарегистр. 10-04-2008 | Отправлено: 14:13 31-01-2022 | Исправлено: serhio61, 15:13 31-01-2022
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
hThr=CreateThread(NULL,0,ThrFunc,ARR,0,NULL);

Всего записей: 1525 | Зарегистр. 01-11-2004 | Отправлено: 15:38 31-01-2022
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Программирование с использованием WinAPI


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru