Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > screenmate - проблемы с SetWindowRgn


Автор: IvanG 3.11.2009, 10:09
Решил разобраться с устройством Скринмейтов (программок бегающих по экрануsmile). Долго мучился с разрезанием картинки и т.д. (С++ знаю не очень...), но тем не менее добился кое-каких результатов.
Скринмейтом полученное творение назвать нельзя, т.к. форма окна и картинка меняется по нажатию клавишь ВВЕРХ, ВНИЗ, выход на Escape. Ну естественно анимации нет. Картинку выдрал из другого скринмейтаsmile

Так вот, теперь собственно о проблеме:
При нажатии клавиш вызывается функция RePaint, которая выводит на окошко другую картинку и устанавливает новую форум окна посредством SetWindowRgn, но тут не все просто, у меня почему то она не всегда меняет форму окна. И тут нет проблем с неправильно заданым регионом и т.д.
Получается что когда мотаешь картинки и форму окна на кнопки ВВЕРХ/ВНИЗ, картинки меняются всегда, а вот форма иногда подтупливает и остается прежняя 
Картинки и формы(регионы) заданы в двух разных массивах.

Прикрепляю архив с компиленным бинарником и исходниками


Код функции RePaint (может в ней проблема?)
Код

void RePaint()
{
    PAINTSTRUCT ps;
    HDC hdcBits;
    HDC hdc;
    SetWindowRgn(hWnd, mask[ind_image], true);
    hdc = BeginPaint(hWnd, &ps);
    hdcBits=::CreateCompatibleDC(hdc);
    SelectObject(hdcBits, bAr[ind_image]);
    BitBlt(hdc, 0, 0, 50, 50, hdcBits, 0, 0, SRCCOPY);
    DeleteDC(hdcBits);
    EndPaint(hWnd, &ps);
    //InvalidateRgn(hWnd, mask[ind_image],false);
    InvalidateRect(hWnd, 0, false);
    return;
}

Автор: mekhanikus 3.11.2009, 12:21
Для начала я бы попробовал в WM_KEYDOWN посылать  InvalidateRgn.

В RePaint заменил бы InvalidateRect  на ValidateRgn.

Хотя, если есть EndPaint, последнее может быть лишнее.

Автор: IvanG 3.11.2009, 14:20
Я не очень силен в винапи, но насколько я успел понять, когда листал справку, ValidateRgn - наоборот устанавливает область которую не надо обновлять.
И сейчас я уже поточнее могу сказать: SetWindowRgn не устанавливает второй раз форму окна по одному и тому же региону, т.е. у меня в программе из массива (170 эл-тов) по очереди (по нажатию клавишь) ставятся разные формы окна и заливаются разными картинками, и по проходу всего этого массива ставится последняя уникальная форма и после не меняется. Тоже самое наблюдается и если прокрутить 5 форм вперед и попробовать вернутся назад, то есть те формы, которые уже ставились, повторно ставится не будут.
Кажется мне надо поусиленне покурить хелпы по этой функции...

Автор: GremlinProg 3.11.2009, 18:10
при нажатии кнопки рисовать ничего не надо, mekhanikus верно подсказывает,
там нужно только сменить регион и вызвать Invalidate,
а рисовать нужно в WM_PAINT

повторно использовать регион для этих нужд и не получится:
Цитата(SetWindowRgn @ MSDN)

After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.

как вариант - делай копию региона через CombineRgn и RGN_COPY и уже эту копию передавай в SetWindowRgn

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)