перерисовка квадрата в новое место
От: boryn Финляндия barisello.h15.ru
Дата: 15.06.05 08:01
Оценка:
такая проблема вот у меня рисуетса квадрат

void Draw(HDC hdc, float& y)
{
Graphics graphics(hdc);

Pen blackPen(Color(255, 0, 0, 0), 3);

RectF rect(0, y, 10, 10);

graphics.DrawRectangle(&blackPen, rect);
}

вот таимер которий двигает етот квадрат


void CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimeID,DWORD dwTime)
{
HDC hdc;
static float y = 0;

hdc = GetDC(hwnd);
Draw(hdc,y+=10);
ReleaseDC(hwnd,hdc);


}

но у меня квадрат не движетса а перерисовываетса на новые координаты как
сделать чтоb он именно двигался
Re: перерисовка квадрата в новое место
От: Аноним  
Дата: 15.06.05 08:24
Оценка:
Здравствуйте, boryn, Вы писали:

B>но у меня квадрат не движетса а перерисовываетса на новые координаты как

B>сделать чтоb он именно двигался

а что значит — двигался ? попробуй пальцем его подтолкнуть
Любое движение это все равно перерисовка.
А мерцание можно убрать так — вернуть из EraseBackground единицу, и плюс сам квадрат перерисовывать в контексте в памяти, а в Draw копировать его на контекст диалога (или по чем ты там рисуешь...)
Re[2]: перерисовка квадрата в новое место
От: boryn Финляндия barisello.h15.ru
Дата: 15.06.05 08:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, boryn, Вы писали:


B>>но у меня квадрат не движетса а перерисовываетса на новые координаты как

B>>сделать чтоb он именно двигался

А>а что значит — двигался ? попробуй пальцем его подтолкнуть

А>Любое движение это все равно перерисовка.
А>А мерцание можно убрать так — вернуть из EraseBackground единицу, и плюс сам квадрат перерисовывать в контексте в памяти, а в Draw копировать его на контекст диалога (или по чем ты там рисуешь...)

мне надо чтобы квадрат передвигалсиа по оси у в низ но он ресуетса заново на форме и у меня получаетса сплошная линия из квадратов
как сделать штоб он именно перемишался на 10 пх каждые 1000 миле секунд типа чтоб после создания 2-го квадрата первый уничтожался
после после создания 2-го квадрата третий уничтожался и так далие
Re[3]: перерисовка квадрата в новое место
От: Аноним  
Дата: 15.06.05 09:11
Оценка:
Здравствуйте, boryn, Вы писали:

B>после после создания 2-го квадрата третий уничтожался и так далие


попробуй сделать y полем класса или глобальным членом (чтоб его было видно в Draw), а в таймере вызывай Invalidate ()

void CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimeID,DWORD dwTime)
{
      y += 10
      Invalidate ();
}


Если это не сработает, перед отрисовкой нового квадрата заливай всю область фоновым цветом, а потом рисуй новый, но первый вариант лучше
А еще лучше и быстрее — создать контекст в памяти, как я уже говорил, и рисовать по нем
Re[3]: перерисовка квадрата в новое место
От: newb  
Дата: 15.06.05 09:15
Оценка:
Здравствуйте, boryn, Вы писали:

B>мне надо чтобы квадрат передвигалсиа по оси у в низ но он ресуетса заново на форме и у меня получаетса сплошная линия из квадратов

B>как сделать штоб он именно перемишался на 10 пх каждые 1000 миле секунд типа чтоб после создания 2-го квадрата первый уничтожался
B>после после создания 2-го квадрата третий уничтожался и так далие
перерисуй его цветом фона
... << RSDN@Home 1.1.3 stable >>
Re[4]: перерисовка квадрата в новое место
От: Аноним  
Дата: 15.06.05 13:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, boryn, Вы писали:


B>>после после создания 2-го квадрата третий уничтожался и так далие


А>попробуй сделать y полем класса или глобальным членом (чтоб его было видно в Draw), а в таймере вызывай Invalidate ()


А>
А>void CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimeID,DWORD dwTime)
А>{
А>      y += 10
А>      Invalidate ();
А>}
А>


А>Если это не сработает, перед отрисовкой нового квадрата заливай всю область фоновым цветом, а потом рисуй новый, но первый вариант лучше

А>А еще лучше и быстрее — создать контекст в памяти, как я уже говорил, и рисовать по нем


A kak создать контекст в памяти
Re[5]: перерисовка квадрата в новое место
От: Аноним  
Дата: 15.06.05 14:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>A kak создать контекст в памяти


Создать контекст не сложно, только я не понимаю, на каком языке ты пишешь — похоже и на С++ и на С#.... Это Java ?
Но так так ты пользуешься API, то разницы особой не будет. В каких местах писать и объявлять данные, разберешься сам

HDC m_dc;         // контекст в памяти
CSize m_dcSize;   // его размер (он может у тебя меняться при резайзе окна - если требуется)
HBRUSH m_brBack;  // кисть для залива фоном
HBRUSH m_brSquare; // кисть для залива квадрата

    //  конструктор
{
     m_dc = NULL;
     m_brBack = CreateSolidBrush (RGB (/* bkColor */));
     m_brSquare = CreateSolidBrush (RGB (/* sqColor */));
}
    // деструктор
{
     DeleteObject (m_brBack);
     DeleteObject (m_brSquare);
     if (m_dc)
          DeleteObject (m_dc);
}
    // функция-инициализатор. Окно еще не показалось, но уже существует. В MFC - это OnInitDialog
{
     RECT r;
     GetClientRect (&r);
     m_dcSize.cx = r.right - r.left;
     m_dcSize.cy = t.bottom - r.top;       // размер контекста у нас будет равен размеру окна

     HDC dc = GetDC (m_hWnd);

              // создаем контекст
     HBITMAP bitm = CreateCompatibleBitmap (dc, m_dcSize.cx, m_dcSize.cy);
     m_dc = CreateCompatibleDC (dc);
     SelectObject (m_dc, bitm);

              // контекст окна больше не нужен
     ReleaseDC (m_hWnd, dc);

               // контекст в памяти создан и находится уже в рабочем состоянии. 
               // Инициализируем его фоновым цветом
     FillRect (m_dc, CRect (0, 0, m_dcSize.cx, m_dcSize.cy), m_brBack);
}

         // рисуем
Draw (HDC dc, ...) {

     if (!m_dc)     // если все сделать правильно, условие никогда не сработает
        return;
 
                    // копируем на контекст диалога наш контекст в памяти
     ::BitBlt (dc, 0, 0, m_dcSize.cx, m_dcSize.cy, m_dc, 0, 0, SRCCOPY);
  
}

        // лучше создать отдельную функцию для рисования, но в данном случае это не принципиально
Timer () {

      static y = 0;
      static x = 0;
      y += 10;
      x += 10;

      FillRect (m_dc, CRect (0, 0, m_dcSize.cx, m_dcSize.cy), m_brBack);
      FillRect (m_dc, CRect (x, y, x + 20, y + 20), m_brSquare);

         // неважно, на чем ты пишешь, но вызывать непосредственно функцию Draw () не рекомендуется
         // посно послать сообщение WM_PAINT, можно вызвать функцию принудительной перерисовки
      Invalidate ();    
}


Все, вроде ничего не упустил. Писал прямо тут , не в редакторе, так что не ругайся если чего
Но это общий случай, если у тебя серьезное рисование. В твоем случае можно все сильно упростить.
Создает контекст в памяти размером квадрата — CSize (20, 20). Сразу заливаем его цветом квадрата и нафиг забываем о нем (вернее, о его перерисовке). Т.е. квадрат нарисован всего один раз, и этого достаточно
В таймере, как у тебя и было в первый раз, меняем значение y. А в Draw меняем его расположение:

Draw (HDC dc, float y) {

     RECT r;
     GetClientRect (&r);
     FillRect (dc, &r, m_brBack);      // запомни эти три строчки. Здесь мы заливаем диалог фоновым цветом

     if (!m_dc)     // если все сделать правильно, условие никогда не сработает
        return;
 
               // копируем на контекст диалога наш контекст в памяти. 
             // координаты копирования - измененные x и y
     ::BitBlt (dc, x, y, m_dcSize.cx, m_dcSize.cy, m_dc, 0, 0, SRCCOPY);
}


У меня сильное подозрение, что ты рисуешь не в стандартном обработчике рисования, иначе у тебя не было бы проблем с остающимся квадратом. Не майся глупостью Создай обработчик перерисовки (OnDraw, по видимому), и те первые три строчки, на которые я обратил внимание, не нужны будут
Re[6]: перерисовка квадрата в новое место
От: boryn Финляндия barisello.h15.ru
Дата: 15.06.05 15:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>A kak создать контекст в памяти


А>Создать контекст не сложно, только я не понимаю, на каком языке ты пишешь — похоже и на С++ и на С#.... Это Java ?

А>Но так так ты пользуешься API, то разницы особой не будет. В каких местах писать и объявлять данные, разберешься сам

А>
А>HDC m_dc;         // контекст в памяти
А>CSize m_dcSize;   // его размер (он может у тебя меняться при резайзе окна - если требуется)
А>HBRUSH m_brBack;  // кисть для залива фоном
А>HBRUSH m_brSquare; // кисть для залива квадрата

А>    //  конструктор
А>{
А>     m_dc = NULL;
А>     m_brBack = CreateSolidBrush (RGB (/* bkColor */));
А>     m_brSquare = CreateSolidBrush (RGB (/* sqColor */));
А>}
А>    // деструктор
А>{
А>     DeleteObject (m_brBack);
А>     DeleteObject (m_brSquare);
А>     if (m_dc)
А>          DeleteObject (m_dc);
А>}
А>    // функция-инициализатор. Окно еще не показалось, но уже существует. В MFC - это OnInitDialog
А>{
А>     RECT r;
А>     GetClientRect (&r);
А>     m_dcSize.cx = r.right - r.left;
А>     m_dcSize.cy = t.bottom - r.top;       // размер контекста у нас будет равен размеру окна

А>     HDC dc = GetDC (m_hWnd);

А>              // создаем контекст
А>     HBITMAP bitm = CreateCompatibleBitmap (dc, m_dcSize.cx, m_dcSize.cy);
А>     m_dc = CreateCompatibleDC (dc);
А>     SelectObject (m_dc, bitm);

А>              // контекст окна больше не нужен
А>     ReleaseDC (m_hWnd, dc);

А>               // контекст в памяти создан и находится уже в рабочем состоянии. 
А>               // Инициализируем его фоновым цветом
А>     FillRect (m_dc, CRect (0, 0, m_dcSize.cx, m_dcSize.cy), m_brBack);
А>}

А>         // рисуем
А>Draw (HDC dc, ...) {

А>     if (!m_dc)     // если все сделать правильно, условие никогда не сработает
А>        return;
 
А>                    // копируем на контекст диалога наш контекст в памяти
А>     ::BitBlt (dc, 0, 0, m_dcSize.cx, m_dcSize.cy, m_dc, 0, 0, SRCCOPY);
  
А>}

А>        // лучше создать отдельную функцию для рисования, но в данном случае это не принципиально
А>Timer () {

А>      static y = 0;
А>      static x = 0;
А>      y += 10;
А>      x += 10;

А>      FillRect (m_dc, CRect (0, 0, m_dcSize.cx, m_dcSize.cy), m_brBack);
А>      FillRect (m_dc, CRect (x, y, x + 20, y + 20), m_brSquare);

А>         // неважно, на чем ты пишешь, но вызывать непосредственно функцию Draw () не рекомендуется
А>         // посно послать сообщение WM_PAINT, можно вызвать функцию принудительной перерисовки
А>      Invalidate ();    
А>}
А>


А>Все, вроде ничего не упустил. Писал прямо тут , не в редакторе, так что не ругайся если чего

А>Но это общий случай, если у тебя серьезное рисование. В твоем случае можно все сильно упростить.
А>Создает контекст в памяти размером квадрата — CSize (20, 20). Сразу заливаем его цветом квадрата и нафиг забываем о нем (вернее, о его перерисовке). Т.е. квадрат нарисован всего один раз, и этого достаточно
А>В таймере, как у тебя и было в первый раз, меняем значение y. А в Draw меняем его расположение:

А>
А>Draw (HDC dc, float y) {

А>     RECT r;
А>     GetClientRect (&r);
А>     FillRect (dc, &r, m_brBack);      // запомни эти три строчки. Здесь мы заливаем диалог фоновым цветом

А>     if (!m_dc)     // если все сделать правильно, условие никогда не сработает
А>        return;
 
А>               // копируем на контекст диалога наш контекст в памяти. 
А>             // координаты копирования - измененные x и y
А>     ::BitBlt (dc, x, y, m_dcSize.cx, m_dcSize.cy, m_dc, 0, 0, SRCCOPY);
А>}
А>


А>У меня сильное подозрение, что ты рисуешь не в стандартном обработчике рисования, иначе у тебя не было бы проблем с остающимся квадратом. Не майся глупостью Создай обработчик перерисовки (OnDraw, по видимому), и те первые три строчки, на которые я обратил внимание, не нужны будут






spasibo ja pisal na c++ win32 api tvoi kod ja neponila tolkam no ja uge sam dogadalsia

vpot tak nado billo


#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
#define ID_TIMER 1

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


float y = 0;
void Draw(HDC hdc)
{
Graphics graphics(hdc);
Pen blackPen(Color(255, 0, 0, 0), 3);
RectF rect(0, y, 10, 10);
graphics.DrawRectangle(&blackPen, rect);
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static char szAppName[] = "Move" ;
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;

// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;

RegisterClassEx (&wndclass) ;

hwnd = CreateWindow (szAppName, "Beeper2 Timer Demo",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;

SetTimer (hwnd, ID_TIMER, 100, NULL);


ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
HBRUSH br;
switch (iMsg)
{
case WM_TIMER:
// Перерисовываем окно по таймеру.
MessageBeep(0);
y+=10;
InvalidateRect(hwnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
Draw(hdc);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY :
KillTimer (hwnd, ID_TIMER) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.