Здравствуйте, boryn, Вы писали:
B>но у меня квадрат не движетса а перерисовываетса на новые координаты как
B>сделать чтоb он именно двигался
а что значит — двигался ?

попробуй пальцем его подтолкнуть

Любое движение это все равно перерисовка.
А мерцание можно убрать так — вернуть из EraseBackground единицу, и плюс сам квадрат перерисовывать в контексте в памяти, а в Draw копировать его на контекст диалога (или по чем ты там рисуешь...)
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, boryn, Вы писали:
B>>но у меня квадрат не движетса а перерисовываетса на новые координаты как
B>>сделать чтоb он именно двигался
А>а что значит — двигался ?
попробуй пальцем его подтолкнуть
А>Любое движение это все равно перерисовка.
А>А мерцание можно убрать так — вернуть из EraseBackground единицу, и плюс сам квадрат перерисовывать в контексте в памяти, а в Draw копировать его на контекст диалога (или по чем ты там рисуешь...)
мне надо чтобы квадрат передвигалсиа по оси у в низ но он ресуетса заново на форме и у меня получаетса сплошная линия из квадратов
как сделать штоб он именно перемишался на 10 пх каждые 1000 миле секунд типа чтоб после создания 2-го квадрата первый уничтожался
после после создания 2-го квадрата третий уничтожался и так далие
Здравствуйте, boryn, Вы писали:
B>после после создания 2-го квадрата третий уничтожался и так далие
попробуй сделать
y полем класса или глобальным членом (чтоб его было видно в Draw), а в таймере вызывай Invalidate ()
void CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimeID,DWORD dwTime)
{
y += 10
Invalidate ();
}
Если это не сработает, перед отрисовкой нового квадрата заливай всю область фоновым цветом, а потом рисуй новый, но первый вариант лучше
А еще лучше и быстрее — создать контекст в памяти, как я уже говорил, и рисовать по нем
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, boryn, Вы писали:
B>>после после создания 2-го квадрата третий уничтожался и так далие
А>попробуй сделать y полем класса или глобальным членом (чтоб его было видно в Draw), а в таймере вызывай Invalidate ()
А>А>void CALLBACK TimerProc(HWND hwnd, UINT iMsg, UINT iTimeID,DWORD dwTime)
А>{
А> y += 10
А> Invalidate ();
А>}
А>
А>Если это не сработает, перед отрисовкой нового квадрата заливай всю область фоновым цветом, а потом рисуй новый, но первый вариант лучше
А>А еще лучше и быстрее — создать контекст в памяти, как я уже говорил, и рисовать по нем
A kak создать контекст в памяти
Здравствуйте, Аноним, Вы писали:
А>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, по видимому), и те первые три строчки, на которые я обратил внимание, не нужны будут
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>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) ;
}