Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>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) ;
}