Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисование 
V
    Опции темы
Tony
  Дата 5.12.2008, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: нет
Всего: 12



Првиет. Рисую на форме с помощю мыши. Если я свора4иваю окно или ресайз, автомтически вызывается WM_PAINT у формы. Понятно форма перерисовывается. Вопрос в том как сохранить нарисованное? Загоняьт в лист или массив а потом в паинт выводить 4то было раньше нарисовано? Как правелно сделать ?  smile 


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
J0ker
Дата 5.12.2008, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



рисовать на совместимом memory DC, а потом копировать через BitBlt когда нужно перерисовать
подсказка чтоб не мучался - неочевидно из документации - совместимый DC надо создавать не к окну, а к экрану - с параметром NULL - CreateCompatibleDC(NULL)
и не забудь создать битмап и выбрать его в DC


--------------------
user posted image
PM MAIL   Вверх
Tony
Дата 6.12.2008, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1159
Регистрация: 3.3.2006
Где: Riga

Репутация: нет
Всего: 12



Пока мало 4то понял, хотябы знаю куда теперь копать. Спасибо за ответ . smile 


--------------------
user posted image
user posted image
PM MAIL Skype   Вверх
MenSem
Дата 6.12.2008, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 10.7.2008

Репутация: нет
Всего: нет



Tony, пример проги:

Код

////////////////////////////////////////////////////////////
// KWnd.cpp
#include "KWnd.h"

KWnd::KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
                   LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM),
                   LPCTSTR menuName, int x, int y, int width, int height,
                   UINT classStyle, DWORD windowStyle, HWND hParent)
{
    char szClassName[] = "KWndClass";

    wc.cbSize        = sizeof(wc);
    wc.style         = classStyle;
    wc.lpfnWndProc   = pWndProc;
    wc.cbClsExtra     = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInst;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = menuName;
    wc.lpszClassName = szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    // Регистрируем класс окна
    if (!RegisterClassEx(&wc)) {
        char msg[100] = "Cannot register class: ";
        strcat(msg, szClassName);
        MessageBox(NULL, msg, "Error", MB_OK);
        return;
    }
    
    // Создаем окно
    hWnd = CreateWindow(szClassName, windowName, windowStyle,
        x, y, width, height, hParent, (HMENU)NULL, hInst, NULL);       
    
    if (!hWnd) {
        char text[100] = "Cannot create window: ";
        strcat(text, windowName);
        MessageBox(NULL, text, "Error", MB_OK);
        return;
    }

    // Показываем  окно
    ShowWindow(hWnd, cmdShow); 
}


////////////////////////////////////////////////////////////
// KWnd.h
#include <windows.h>

class KWnd {
public:    
    KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
        LRESULT (WINAPI *pWndProc)(HWND,UINT,WPARAM,LPARAM),
        LPCTSTR menuName = NULL,
        int x = CW_USEDEFAULT, int y = 0,
        int width = CW_USEDEFAULT, int height = 0,
        UINT classStyle =  CS_HREDRAW | CS_VREDRAW,
        DWORD windowStyle = WS_OVERLAPPEDWINDOW,
        HWND hParent = NULL);

    HWND GetHWnd() { return hWnd; }
protected:
    HWND hWnd;  
    WNDCLASSEX wc;
};


//////////////////////////////////////////////////////////////////////
// ScribbleAdv.cpp
#include <windows.h>
#include <vector>
using namespace std; 

#include "KWnd.h"

struct Point {
    Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
    int x;
    int y;
};

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//====================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    KWnd mainWnd("ScribbleAdvanced", hInstance, nCmdShow, WndProc);    

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

//====================================================================
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HDC hDC; // контекст устройства для рисования мышью
    HDC hdc;     // контекст устройства для восстановления
                 // рисунка при обработке WM_PAINT
    PAINTSTRUCT ps;
    static int x, y;  // позиция курсора мыши
    static BOOL bTracking = FALSE;

    static vector<Point> curve;
    static vector<vector<Point> > curves;
    vector<Point>::iterator it;

    int i, j;

    switch (uMsg)
    {
    case WM_CREATE:
        hDC = GetDC(hWnd);
        break;

    case WM_LBUTTONDOWN: 
        bTracking = TRUE;
        // начальная позиция
        x = LOWORD(lParam);
        y = HIWORD(lParam);
        MoveToEx(hDC, x, y, NULL);
        curve.push_back(Point(x, y));
        break; 
 
    case WM_LBUTTONUP:
        if (bTracking) {
            bTracking = FALSE; 
            curves.push_back(curve);
            curve.clear();
        }
        break; 
 
    case WM_MOUSEMOVE: 
        if (bTracking) {
            // новая позиция
            x = LOWORD(lParam);
            y = HIWORD(lParam);
            LineTo(hDC, x, y);
            curve.push_back(Point(x, y));
        } 
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        for (i = 0; i < curves.size(); ++i) {
            it = curves[i].begin();
            MoveToEx(hdc, it->x, it->y, NULL);
            for (it + 1; it != curves[i].end(); ++it)
                LineTo(hdc, it->x, it->y);
        }
        EndPaint(hWnd, &ps);
        break;

    case WM_DESTROY:    
        ReleaseDC(hWnd, hDC); 
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
//////////////////////////////////////////////////////////////////////

--------------------
PM MAIL   Вверх
MenSem
Дата 6.12.2008, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 10.7.2008

Репутация: нет
Всего: нет



J0ker, интересно. Пробовал - не получилось.
--------------------
PM MAIL   Вверх
J0ker
Дата 7.12.2008, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



немного ошибся выше
CreateCompatibleDC(GetDC(NULL));
Код

HDC memDC = CreateCompatibleDC(GetDC(NULL));
HBITMAP bmp = CreateCompatibleBitmap(GetDC(NULL), sx, sy);
DeleteObject(SelectObject(memDC, bmp));

// рисуем на memDC


// когда надо обновить окно
BitBlt(WndDC, 0, 0, sx, sy, memDC, 0, 0, SRCCOPY);


// cleanup
DeleteObject(bmp);
DeleteDC(memDC);



Это сообщение отредактировал(а) J0ker - 7.12.2008, 00:03


--------------------
user posted image
PM MAIL   Вверх
MenSem
Дата 7.12.2008, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 10.7.2008

Репутация: нет
Всего: нет



Код

HDC memDC = CreateCompatibleDC(GetDC(NULL));
HBITMAP bmp = CreateCompatibleBitmap(GetDC(NULL), sx, sy);
DeleteObject(SelectObject(memDC, bmp));


Это в WM_CREATE ? Переменные static?

Код

// когда надо обновить окно
BitBlt(WndDC, 0, 0, sx, sy, memDC, 0, 0, SRCCOPY);


Здесь WndDC = BeginPaint(hWnd, &ps) ?

Это сообщение отредактировал(а) MenSem - 7.12.2008, 18:22
--------------------
PM MAIL   Вверх
J0ker
Дата 7.12.2008, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(MenSem @  7.12.2008,  18:18 Найти цитируемый пост)
Это в WM_CREATE ? Переменные static?

где угодно и как угодно
memDC - объект существующий на протяжении всей жизни окна ессесна
там нужны размеры битмапа - это можно делать по разному - можно сразу создать максимальный битмап, а можно пересоздавать битмап на WM_SIZE, перевыбирать его и перерисовавать на memDC содержимое

Цитата(MenSem @  7.12.2008,  18:18 Найти цитируемый пост)
Здесь WndDC = BeginPaint(hWnd, &ps) ?

Код

case WM_PAINT:
        WinDC = BeginPaint(hWnd, &ps);
        BitBlt(WndDC, 0, 0, sx, sy, memDC, 0, 0, SRCCOPY);
        EndPaint(hWnd, &ps);




--------------------
user posted image
PM MAIL   Вверх
maxim1000
Дата 7.12.2008, 21:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата(J0ker @  7.12.2008,  00:03 Найти цитируемый пост)
HDC memDC = CreateCompatibleDC(GetDC(NULL));

судя по документации, надо бы запомнить результат GetDC(NULL) и вызвать для него ReleaseDC


--------------------
qqq
PM WWW   Вверх
MenSem
Дата 7.12.2008, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 10.7.2008

Репутация: нет
Всего: нет



maxim1000, без учета этого - появляется черный квадрат и рисование мышью не работает, с учетом - квадрата нет, но рисование не работает.
--------------------
PM MAIL   Вверх
J0ker
Дата 7.12.2008, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Цитата(maxim1000 @ 7.12.2008,  21:00)
Цитата(J0ker @  7.12.2008,  00:03 Найти цитируемый пост)
HDC memDC = CreateCompatibleDC(GetDC(NULL));

судя по документации, надо бы запомнить результат GetDC(NULL) и вызвать для него ReleaseDC

да, совершенно правильно сорри забыл


--------------------
user posted image
PM MAIL   Вверх
maxim1000
Дата 7.12.2008, 22:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 2
Всего: 110



Цитата(MenSem @  7.12.2008,  21:11 Найти цитируемый пост)
без учета этого - появляется черный квадрат и рисование мышью не работает, с учетом - квадрата нет, но рисование не работает. 

тут лучше бы привести код, а то вслепую сложно получается...


--------------------
qqq
PM WWW   Вверх
J0ker
Дата 7.12.2008, 22:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



это не черный квадрат - битмап заполнен нулями - черный цвет
перед рисованием нарисуй белый квадрат на весь размер


--------------------
user posted image
PM MAIL   Вверх
MenSem
Дата 8.12.2008, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 157
Регистрация: 10.7.2008

Репутация: нет
Всего: нет



Цитата(J0ker @  7.12.2008,  22:42 Найти цитируемый пост)
перед рисованием нарисуй белый квадрат на весь размер

В первом варианте работает

Это сообщение отредактировал(а) MenSem - 16.12.2008, 19:55
--------------------
PM MAIL   Вверх
J0ker
Дата 8.12.2008, 03:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: -1
Всего: 14



Код

                                case WM_CREATE:
                {
                    HDC tdc = GetDC(NULL);
                    memDC= CreateCompatibleDC(tdc);
                    bmp = CreateCompatibleBitmap(tdc, 150, 150);
                    ReleaseDC(NULL,tdc);
                    DeleteObject(SelectObject(memDC, bmp)); 
                }
                    break;


остальное не смотрел


--------------------
user posted image
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1013 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.