Движение окружности

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
vadim_77
Сообщения: 3
Зарегистрирован: 01 авг 2017, 15:17

01 авг 2017, 15:46

Здравствуйте. Когда использую координаты мышки у меня получается рисование а движение только в верхнем левом углу в квадрате. А как мне сделать так чтобы было движение и как мне убрать квадрат в левом верхнем углу?

Код: Выделить всё

#include <windows.h>
#include <iostream>
 
int InputInteger(const char * str, int min, int max) {
    int x;
    std::cout << str;
    bool ErrorFlag;
    do {
        std::cin.clear();
        std::cin.ignore(std::cin.rdbuf()->in_avail());
        std::cin >> x;
        ErrorFlag = !std::cin.good() || x< min || x>max;
        if (ErrorFlag) {
            std::cout << "Error. " << str;
        }
    } while (ErrorFlag);
    std::cin.ignore(std::cin.rdbuf()->in_avail());
    return x;
}
 
HWND GetConsoleHwnd(void) {
#define MY_BUFSIZE 1024
    HWND hwndFound;
    char pszNewWindowTitle[MY_BUFSIZE];
    char pszOldWindowTitle[MY_BUFSIZE];
    GetConsoleTitle(LPWSTR(pszOldWindowTitle), MY_BUFSIZE);
    wsprintf(LPWSTR(pszNewWindowTitle), LPCWSTR("%d/%d"),
        GetTickCount(),
        GetCurrentProcessId());
    SetConsoleTitle(LPCWSTR(pszNewWindowTitle));
    Sleep(1);
    hwndFound = FindWindow(NULL, LPCWSTR(pszNewWindowTitle));
    SetConsoleTitle(LPCWSTR(pszOldWindowTitle));
    return(hwndFound);
}
 
int main() {
    RECT o;
    POINT p;
    HWND wh = GetConsoleHwnd();
    /* COORD c = { 50,10 }; */
 
    HWND hWnd = GetConsoleWindow();
    HDC hDC = GetDC(hWnd);
    RECT temp;
    GetClientRect(hWnd, &temp);
    HDC hBufferDC = CreateCompatibleDC(hDC);
    HBITMAP hBufferBmp = CreateBitmap(temp.right, temp.bottom, 1, 32, NULL);
    HBITMAP hBufferBmpOld = (HBITMAP)SelectObject(hBufferDC, hBufferBmp);
    FillRect(hBufferDC, &temp, (HBRUSH)GetStockObject(WHITE_BRUSH));
    std::cout << "Enter color:\n";
    int r, g, b;
    r = InputInteger("Enter R value[0,255]:", 0, 255);
    g = InputInteger("Enter G value[0,255]:", 0, 255);
    b = InputInteger("Enter B value[0,255]:", 0, 255);
    system("cls");
    HBRUSH hBrush = CreateSolidBrush(RGB(r, g, b));
    HPEN hPen = CreatePen(PS_SOLID, 1, RGB(r, g, b));
    HBRUSH hOldBrush = (HBRUSH)SelectObject(hBufferDC, hBrush);
    HPEN hOldPen = (HPEN)SelectObject(hBufferDC, hPen);
    RECT circle = { 0, 0, 100, 100 };
    size_t step_h = 1, step_v = 1;
    while (!GetAsyncKeyState(VK_ESCAPE)) {
 
        GetWindowRect(wh, &o);
        GetCursorPos(&p);
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { 0,0 });
 
        FillRect(hBufferDC, &circle, (HBRUSH)GetStockObject(WHITE_BRUSH));
        /* if (GetAsyncKeyState(VK_LEFT)) {
        circle.left -= step_h;
        circle.right -= step_h;
        }
        if (GetAsyncKeyState(VK_RIGHT)) {
        circle.left += step_h;
        circle.right += step_h;
        }
        if (GetAsyncKeyState(VK_DOWN)) {
        circle.top += step_v;
        circle.bottom += step_v;
        }
        if (GetAsyncKeyState(VK_UP)) {
        circle.top -= step_v;
        circle.bottom -= step_v;
        }  */
 
        Ellipse(hBufferDC, p.x, p.y, p.x + 50, p.y + 50); 
        /* Ellipse(hBufferDC, circle.left, circle.top, circle.right, circle.bottom); */
        BitBlt(hDC, 0, 0, temp.right, temp.bottom, hBufferDC, 0, 0, SRCCOPY);
        /* std::cout << circle.left << ":" << circle.top << ":" << circle.right << ":" << circle.bottom << std::endl; */
        std::cout << p.x << ":" << p.y << ":" << p.x + 50 << ":" << p.y + 50 << std::endl;
        Sleep(10);
    }
    SelectObject(hBufferDC, hOldBrush);
    SelectObject(hBufferDC, hOldPen);
    SelectObject(hBufferDC, hBufferBmpOld);
    DeleteObject(hBrush);
    DeleteObject(hPen);
    DeleteObject(hBufferBmp);
    DeleteDC(hBufferDC);
    ReleaseDC(hWnd, hDC);
    return 0;
}
Изображение
Skwoogey
Сообщения: 63
Зарегистрирован: 11 янв 2016, 02:25

01 авг 2017, 19:56

в winAPI не силен, но с курсором работал. В общем, функция GetCursorPos возвращает координаты курсора относительно координат экрана. Их надо перевести в систему координат окна функцией ScreenToClient. Предположу, что графический контекст работает тоже в координатах окна. Проблема скорее всего в этом.

/*ниже будут мои предположения и спекуляции, которые могут сильно отличаться от реальности*/

По поводу квадрата я бы сказал, что это функция BitBlt. Она копирует прямоугольное поле из одного графического контекста и вставляет в другое. А ты его как раз вставляешь в начало координат, иными словами левый верхний угол.

/*еще больше спекуляций*/

Я предположу, что это должна была быть система с двойным буфером, хотя могу ошибаться. В таком случае надо копировать все содержимое контекста. Тебе надо получить ширину и высоту контекста, а координаты нижнего правого угла окна обычно не совпадают с ними (наверное). Есть вот такая тема на stackoverflow. Может поможет.

Как я и говорил, в winAPI не силен, но может помог или натолкнул на верную мысль. Позже, скорее всего, придут люди поумнее меня и поправят/дополнят мой ответ.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

01 авг 2017, 20:41

А почему бы тебе не построить нормальный WinAPI или WTL проект? В Вижуал Студии (она теперь бесплатная) есть такой шаблон.
2B OR NOT(2B) = FF
vadim_77
Сообщения: 3
Зарегистрирован: 01 авг 2017, 15:17

01 авг 2017, 21:08

Перевел в систему координат ScreenToClient, но это не помогло. А верхний левый угол это не функция BitBlt. Она отвечает за координаты белого фона там где происходит рисование, а квадратик остается.
vadim_77
Сообщения: 3
Зарегистрирован: 01 авг 2017, 15:17

01 авг 2017, 21:19

Absurd, если бы я знал как это делается, я бы давно уже построил. У меня ATL только есть а WTL нету. Может покажешь пример как это делается?
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

01 авг 2017, 21:26

vadim_77 писал(а):Absurd, если бы я знал как это делается, я бы давно уже построил. У меня ATL только есть а WTL нету. Может покажешь пример как это делается?

Он ставится в виде плагина на Студию. Написали вроде сами MS, но библиотека не официальная, и поскольку ATL они забросили, то она никогда не будет официальной.

https://sourceforge.net/projects/wtl/

В качестве туториала по WTL выступает этот цикл статей.

https://www.codeproject.com/Articles/38 ... UI-Classes
2B OR NOT(2B) = FF
Ответить