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...
Пока на собственное сообщение не было ответов, его можно удалить.