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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двойная буферизация - как правильно? CreateDIBSection возвращает FALSE 
V
    Опции темы
Arks
  Дата 17.9.2007, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



В общих словах:
Требуется использовать двойную буферизацию. В буфере в памяти надо программно рисовать цветные примитивы (линии, треугольники).

Вот таким образом я пытался реализовать двойную буферизацию по примеру с мсднки (с онлайна откуда-то):
Код

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    static HDC cdc = NULL;
    static HPEN pen = NULL;
    static HBITMAP bmp = NULL;
    static GObject *obj = NULL;
    static Scene scn;
    float xleft, xright, top, bottom, znear, zfar;    // координаты для перспективной проекции
    double alpha;    // угол для перспективной проекции
    float b;    // длина стороны паралельно y (a - паралельной x) у ближней отсекающей плоскости
    static int width, height;    // размеры области рисования
    RECT myrect;

    switch (message)
    {
    case WM_CREATE:
        obj = new GObject();
        break;
    . . .
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        hdc = GetDC(hWnd);
        
        if(!cdc)
        {
            cdc = CreateCompatibleDC(hdc);
            //bmp = CreateCompatibleBitmap(hdc,width,height);
            BITMAPINFO i;
            ZeroMemory( &i.bmiHeader, sizeof(BITMAPINFOHEADER) );
            i.bmiHeader.biWidth=width;     // Set size you need
            i.bmiHeader.biHeight=height;    // Set size you need
            i.bmiHeader.biPlanes=1;
            i.bmiHeader.biBitCount=24; // Can be 8, 16, 32 bpp or
                                       // other number
            i.bmiHeader.biSizeImage=0;
            i.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
            i.bmiHeader.biClrUsed= 0;
            i.bmiHeader.biClrImportant= 0; */
            VOID *pvBits;
            bmp= CreateDIBSection( hdc,
                                            &i,
                                            DIB_RGB_COLORS,
                                            &pvBits,
                                            NULL,
                                            0 );
        
            pen = CreatePen(PS_SOLID,10,RGB(1,0,0));
            pen = (HPEN) SelectObject(cdc,pen);
        }
        SelectObject(cdc,bmp);
        scn.Render(cdc,hdc);
        BitBlt(hdc,0,0,width,height,cdc,0,0,SRCPAINT);

        ReleaseDC(hWnd,hdc);
        break;
    case WM_DESTROY:
        pen = (HPEN) SelectObject(cdc,pen);
        DeleteObject(pen);
        DeleteObject(bmp);
        DeleteDC(cdc);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


Потом нашёл вот эту тему: CreateDIBSection - нужен пример юзания
Попытался реализовать, как написано там. Вот что вышло:
Код

BOOL MyCreateDIBSection(HDC hDC,HBITMAP m_hBitmap,UINT nWidth,UINT nHeight,WORD nBitCnt,LPVOID m_pBits,LPRGBQUAD pColors)
{
    // создаем "упакованную" структуру BITMAPINFO
    int  nCols=1<<nBitCnt;
    UINT nSize=sizeof(BITMAPINFOHEADER);
    if (nBitCnt <= 8) 
        nSize+=+nCols*sizeof(RGBQUAD);
    
    m_pBmi=(LPBITMAPINFO) new char [nSize];
    if (!m_pBmi) return FALSE;
    // заполняем ее ...
    m_pBmih=(BITMAPINFOHEADER*)&m_pBmi->bmiHeader;
    m_pColors=(nBitCnt <= 8)?m_pBmi->bmiColors:NULL;
    memset (m_pBmih,0,sizeof(BITMAPINFOHEADER));
    
    m_pBmih->biSize         =sizeof(BITMAPINFOHEADER);
    m_pBmih->biWidth         =nWidth; 
    m_pBmih->biHeight         =nHeight; 
    m_pBmih->biPlanes         =1; 
    m_pBmih->biBitCount     =nBitCnt; 
    m_pBmih->biCompression=BI_RGB; 
    m_pBmih->biClrUsed     =(nBitCnt <= 8)?nCols:0;
    m_pBmih->biXPelsPerMeter=m_pBmih->biYPelsPerMeter=(LONG)(300/0.024);
    DWORD nUseColors=DIB_RGB_COLORS;
    if (pColors && m_pColors) {
        // копируем переданную таблицу цветов - считаем ее полной
        memcpy (m_pColors,pColors,nCols*sizeof(RGBQUAD));
    }
    else if (nBitCnt==1) {
        memset (m_pColors,0,sizeof(RGBQUAD)*2);
        m_pColors[1].rgbRed=m_pColors[1].rgbGreen=m_pColors[1].rgbBlue=255;
    }
    else if (nBitCnt <= 8) {    
        // заполняем таблицу цветов прямыми ссылками на системную таблицу
        LPWORD pIndex=(LPWORD)m_pColors;
        for (int i=0; i < nCols; i++) *pIndex++=i;
        nUseColors=DIB_PAL_COLORS;
    }
    m_hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,(LPVOID*)&m_pBits,NULL,NULL);
    if (!m_hBitmap) return FALSE;
    return TRUE;
}

//-------------------------------------------------------------------------------------------------------------------

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    static HDC cdc = NULL;
    static HPEN pen = NULL;
    static HBITMAP bmp = NULL;
    static GObject *obj = NULL;
    static Scene scn;
    float xleft, xright, top, bottom, znear, zfar;    // координаты для перспективной проекции
    double alpha;    // угол для перспективной проекции
    float b;    // длина стороны паралельно y (a - паралельной x) у ближней отсекающей плоскости
    static int width, height;    // размеры области рисования
    RECT myrect;

    switch (message)
    {
    case WM_CREATE:
        obj = new GObject();
        break;
    . . .
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        hdc = GetDC(hWnd);
        
        if(!cdc)
        {
            cdc = CreateCompatibleDC(hdc);
            VOID *pvBits;
            BOOL b;
            b = MyCreateDIBSection( hdc,bmp,width,height,24,&pvBits,NULL );
            if(!b)
                MessageBoxA(hWnd,"false","",MB_OK|MB_ICONEXCLAMATION);
            else
                MessageBoxA(hWnd,"true","",MB_OK|MB_ICONEXCLAMATION);

            pen = CreatePen(PS_SOLID,10,RGB(1,0,0));
            pen = (HPEN) SelectObject(cdc,pen);
        }
        SelectObject(cdc,bmp);
        scn.Render(cdc,hdc);
        BitBlt(hdc,0,0,width,height,cdc,0,0,SRCPAINT);

        ReleaseDC(hWnd,hdc);
        break;
    case WM_DESTROY:
        pen = (HPEN) SelectObject(cdc,pen);
        DeleteObject(pen);
        DeleteObject(bmp);
        DeleteDC(cdc);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


Проблема в том, что CreateDIBSection возвращает NULL, т.е. ничего не создаёт.

Надеюсь получить разяснения или хотя бы пример - полноценный рабочий код (ссылку на него)  smile 

Это сообщение отредактировал(а) Arks - 17.9.2007, 19:50
PM MAIL ICQ Skype MSN   Вверх
Mihhail
Дата 18.9.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здесь полно мелких огрехов, они и бъют общий замысел.
    
Первое: почему static HDC cdc = NULL; объявляется локально? Так он при каждой перерисовке будет создаваться занова. Всё что в WM_DESTROY удаляется должно в WM_CREATE создаваться и объявляться глобально.

Второе: Какая то свистопляска с указателем VOID *pvBits;. CreateDIBSection просто не получает нужного для работы. Без "наворотов" будет так:    
    b = MyCreateDIBSection( hdc,bmp,width,height,24,pvBits,NULL );
    ---------------------------
    BOOL MyCreateDIBSection(HDC hDC,HBITMAP m_hBitmap,UINT nWidth,UINT nHeight,WORD nBitCnt,LPVOID m_pBits,LPRGBQUAD pColors)
    ---------------------------
    m_hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,m_pBits,NULL,NULL);

Третье: 
Цитата(Arks @  17.9.2007,  23:47 Найти цитируемый пост)
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
hdc = GetDC(hWnd);

Даю перевод из справки:
Цитата
Функция BeginPaint подготавливает определенное окно к живописи и заполняет структуру PAINTSTRUCT информацией о painting.

Цитата
Функция EndPaint маркирует конец живописи определенным окном. Эта функция необходима для каждого вызова на BeginPaint функция, но только после того, как живопись завершиться.

Т.е. EndPaint в самый конец манипуляций отрисовки, а hdc = GetDC(hWnd); это лишнее.

Это сообщение отредактировал(а) Mihhail - 18.9.2007, 18:43
PM MAIL WWW   Вверх
Arks
Дата 18.9.2007, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата
Первое: почему static HDC cdc = NULL; объявляется локально? Так он при каждой перерисовке будет создаваться занова.

Нет, т.к. это статическая переменная. Впрочем, на всякий пожарный, я изменил код. Смотрите первый листинг.

Цитата
Второе: Какая то свистопляска с указателем VOID *pvBits

Так в том то и дело, что CreateDIBSection имеет следующий прототип:
HBITMAP CreateDIBSection( HDC hdc, CONST BITMAPINFO *pbmi, UINT iUsage, VOID **ppvBits, HANDLE hSection, DWORD dwOffset);

Туда надо передавать void** иначе вообще не компилится.

На счёт третьего, спасибо, что указали. Только один вопрос: а если рисуется за областью отсечения? Что будет? Просто не выведет на экран?

Код

HDC cdc;
HPEN pen;
HBITMAP bmp;
GObject *obj;
HGDIOBJ hOld;
Scene scn;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    float xleft, xright, top, bottom, znear, zfar;    // координаты для перспективной проекции
    double alpha;    // угол для перспективной проекции
    float b;    // длина стороны паралельно y (a - паралельной x) у ближней отсекающей плоскости
    static int width, height;    // размеры области рисования
    RECT myrect;

    switch (message)
    {
    case WM_CREATE:
        obj = new GObject();
        cdc = NULL;
        pen = NULL;
        bmp = NULL;
        hOld = NULL;
        break;
    case WM_COMMAND:
        ...
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        if(!hdc)
            MessageBoxA(hWnd,"Failed to create hdc","",MB_OK|MB_ICONEXCLAMATION);
        
        if(!cdc)
        {
            cdc = CreateCompatibleDC(hdc);
            //bmp = CreateCompatibleBitmap(hdc,width,height);
            BITMAPINFO i;
            ZeroMemory( &i.bmiHeader, sizeof(BITMAPINFOHEADER) );
            i.bmiHeader.biWidth=width;     // Set size you need
            i.bmiHeader.biHeight=height;    // Set size you need
            i.bmiHeader.biPlanes=1;
            i.bmiHeader.biBitCount=24; // Can be 8, 16, 32 bpp or
                                       // other number
            i.bmiHeader.biSizeImage=0;
            i.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
            i.bmiHeader.biClrUsed= 0;
            i.bmiHeader.biClrImportant= 0; 
            VOID *pvBits;
            bmp= CreateDIBSection( hdc,
                                            &i,
                                            DIB_RGB_COLORS,
                                            &pvBits,
                                            NULL,
                                            0 );
            if(!bmp)
            {
                MyGetLastError(hWnd);
            }
            if(!SelectObject(cdc,bmp))
            {
                MyGetLastError(hWnd);
            }
        
            pen = CreatePen(PS_SOLID,10,RGB(1,0,0));
            pen = (HPEN) SelectObject(cdc,pen);
        }
        MoveToEx(hdc,100,100,NULL);
        LineTo(hdc,500,500);
        Rectangle(cdc,10,10,600,500);
        scn.Render(cdc,hdc);
        if(!BitBlt(hdc,0,0,width,height,cdc,0,0,SRCCOPY))
        {
            MyGetLastError(hWnd);
            MessageBoxA(hWnd,"BitBlt didn't worked","",MB_OK|MB_ICONEXCLAMATION);
        }

        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        pen = (HPEN) SelectObject(cdc,pen);
        hOld = SelectObject(cdc,bmp);
        DeleteObject(hOld);
        DeleteObject(pen);
        DeleteDC(cdc);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


Итог: то что рисуется в cdc так и не рисуется. Нашёл странность:
                        bmp= CreateDIBSection( ... );
            if(!bmp)
            {
                MyGetLastError(hWnd);
            }
            if(!SelectObject(cdc,bmp))
            {
                MyGetLastError(hWnd);
            }
Вот здесь обе MyGetLastError выполняются! При этом оба раза GetLastError возвращает 0, т.е. "Операция завершена успешно".
MyGetLastError:
Код

void MyGetLastError(HWND hwnd)
{
  DWORD error = GetLastError();
//  if( !error )
//    return;

    char*lpvErrorMsg;
    FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, 
                   error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                   (char *)&lpvErrorMsg, 0, NULL );

    MessageBoxA(hwnd,lpvErrorMsg,"GetLastError: ",MB_OK|MB_ICONEXCLAMATION);
}

PM MAIL ICQ Skype MSN   Вверх
Mihhail
Дата 19.9.2007, 07:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Arks @  19.9.2007,  01:39 Найти цитируемый пост)
Так в том то и дело, что CreateDIBSection имеет следующий прототип:HBITMAP CreateDIBSection( HDC hdc, CONST BITMAPINFO *pbmi, UINT iUsage, VOID **ppvBits, HANDLE hSection, DWORD dwOffset);

Откуда эти сведения?
Привожу выписки из справки о функции CreateDIBSection(перевод Сократа):
Цитата

HBITMAP CreateDIBSection(
    HDC hdc,    // handle to device context
    CONST BITMAPINFO *pbmi,    // pointer to structure containing bitmap size, format, and color data
    UINT iUsage,    // color data type indicator: RGB values or palette indices
    VOID *ppvBits,    // указатель в переменную, чтобы получать указатель в битовые величины побитового отображения
    HANDLE hSection,    // optional handle to a file mapping object
    DWORD dwOffset    // offset to the bitmap bit values within the file mapping object
   );
............................
ppvBits
Точки на переменную, которые получают указатель в позицию битовых величин машинонезависимого побитового отображения.
............................
Если функция добивается успеха, обратная величина является ручкой в вновь созданное машинонезависимое побитовое отображение, и *ppvBits указывает на бит побитового отображения values.
Если функция терпит неудачу, обратная величина - НЕДЕЙСТВИТЕЛЬНА, и *ppvBits НЕДЕЙСТВИТЕЛЕН.

VOID *pvBits; тоже в глобальные!

Цитата(Arks @  19.9.2007,  01:39 Найти цитируемый пост)
На счёт третьего, спасибо, что указали. Только один вопрос: а если рисуется за областью отсечения? Что будет? Просто не выведет на экран?

Да, вывод осуществляется только в пределах существующих координат картинки(HBITMAP) контекста(HDC), отсекаются все попытки вывода за их пределами, как в плюс так и в минус, как в буфуре так и на экране.
Можно буфер сделать больше нежели окно вывода, тогда можно будет обеспечить прокрутку изображения. Т.е. изменять координаты X и Y и вставляя их в BitBlt(hdc,0,0,width,height,cdc,X,Y,SRCCOPY)
PM MAIL WWW   Вверх
Arks
Дата 19.9.2007, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



1ый источник - компилятор, который ваш код не пропускает smile
2ой - МСДН:
Цитата
HBITMAP CreateDIBSection(
  HDC hdc,                 // handle to DC
  CONST BITMAPINFO *pbmi,  // bitmap data
  UINT iUsage,             // data type indicator
  VOID **ppvBits,          // bit values
  HANDLE hSection,         // handle to file mapping object
  DWORD dwOffset     // offset to bitmap bit values
);
Return Values

If the function succeeds, the return value is a handle to the newly created DIB, and *ppvBits points to the bitmap bit values. 

http://msdn2.microsoft.com/en-us/library/ms532292.aspx

Читать надо первоисточники.   smile

Это сообщение отредактировал(а) Arks - 19.9.2007, 14:41
PM MAIL ICQ Skype MSN   Вверх
Earnest
Дата 19.9.2007, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



1) ppBits действительно должно быть указателем на LPVOID, т.е. на адрес переменной, куда положат адрес выделенного буфера.
2) Твоя MyCreateDIBSection в любом случае не будет работать (даже если секция внутри создастся). 
Код

BOOL MyCreateDIBSection(HDC hDC,HBITMAP m_hBitmap,UINT nWidth,UINT nHeight,WORD nBitCnt,LPVOID m_pBits,LPRGBQUAD pColors)

Причина - ты передаешь возвращаемые параметры по-значению. И как ты собрался ими пользоваться?.
Ты бы внимательно пост прочитал. Видмо, если CreateDIBSection возвращает 0, стало быть с параметрами что-то не так.




--------------------
...
PM   Вверх
Arks
Дата 19.9.2007, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Ах, и вправду по значению. Правда, я использовал не её, а вызывал саму CreateDIBSection. Но исправил, попробовал через неё запустить. Не заработало.
Исправил, т.е. так:
Код
VOID *m_pBits;

BOOL MyCreateDIBSection(HDC hDC,HBITMAP m_hBitmap,UINT nWidth,UINT nHeight,WORD nBitCnt,LPRGBQUAD pColors)
{
   ...    // тут всё по старому
  m_hBitmap=CreateDIBSection (hDC,m_pBmi,nUseColors,&m_pBits,NULL,NULL);
    if (!m_hBitmap) return FALSE;
    return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    ...
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        if(!hdc)
            MessageBoxA(hWnd,"Failed to create hdc","",MB_OK|MB_ICONEXCLAMATION);
        
        if(!cdc)
        {
            cdc = CreateCompatibleDC(hdc);
            if(!MyCreateDIBSection(NULL,bmp,width,height,24,NULL))
            {
                MyGetLastError(hWnd);
            }
            if(SelectObject(cdc,bmp)==NULL)
            {
                MyGetLastError(hWnd);
            }
        
            pen = CreatePen(PS_SOLID,10,RGB(1,0,0));
            pen = (HPEN) SelectObject(cdc,pen);
        }
    ...
}

Результат тот же (MyCreateDIBSection вернула 0), ничего не создалось. Меня одно смущает: почему MyGetLastError при коде ошибки 0 выводит "Операция успешно завершена." Она ведь не завершена, или по крайней мере не успешно!

Если не сложно, посмотрите мою прогу сами. И не гневайтесь сильно, что туплю... Я в винапи ещё совсем плаваю. Лучше книжечку серьёзную (связанную с интерфейсом и GDI - очень нужно, т.к. весь семестр рисованием разным заниматься буду) посоветуйте.
моя прога

А Михаил и вправду неверные данные дал. Может конечно Сократ их покоцал? Впрочем, извиняюсь, если не очень корректно ответил.

Это сообщение отредактировал(а) Arks - 19.9.2007, 20:25
PM MAIL ICQ Skype MSN   Вверх
Mihhail
Дата 19.9.2007, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Arks @  20.9.2007,  00:20 Найти цитируемый пост)
А Михаил и вправду неверные данные дал. Может конечно Сократ их покоцал? Впрочем, извиняюсь, если не очень корректно ответил.

Действительно в справке ошибка с указателем, да и по названию переменной ppvBits можно догадаться о типе. Mea culpa!  smile
Нашёл я у себя объявление этой функции:
WINGDIAPI HBITMAP WINAPI CreateDIBSection( IN HDC, IN CONST BITMAPINFO *, IN UINT, OUT VOID **, IN HANDLE, IN DWORD);

Скачал я программку. У меня сначала была такая же ерунда с bmp, помогло изменение типа переменной.
Вот ключевые моменты в коде:
Код
VOID **pvBits;    //Гобальное объявление
.....................
case WM_CREATE:
   cdc = NULL;
   pen = NULL;
   bmp = NULL;
   hOld = NULL;
   pvBits = (VOID**)malloc( sizeof(VOID*) );
   break;
.....................
bmp = CreateDIBSection( hdc, &i, DIB_RGB_COLORS, pvBits, NULL, 0 );
.....................

Ещё один момент, перед заполнением структуры  BITMAPINFO i; должны быть уже известны width и height!

Arks у вас в задании сказано что нужна именно CreateDIBSection?
А то ведь есть очень простая функция создания картинки:
HBITMAP CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight );
Никаких дополнительных заморочек, только ширина и высота!    smile 


Это сообщение отредактировал(а) Mihhail - 19.9.2007, 23:28
PM MAIL WWW   Вверх
Arks
Дата 20.9.2007, 07:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Михаил, у меня в задания в принципе не указано, какими средствами и даже на каком языке я должен это делать. Надо чтобы программа задание выполняла, а остальное мои заботы.  smile 


Кстати, с CreateCompatibleBitmap я тоже пытался написать. Только что получилось, основная ошибка и там и там, я в другом сообщении заполнял width и height. И при первом вызове WM_PAINT они были не инициализированы. Также здесь я создал VOID **m_pBits; как вы порекомендовали. Заработало.

Прикол:
Заработал именно вызов CreateDIBSection из WM_PAINT. При использовании же той, не моей функции, которая кучу всего делает при заполнении BITMAPINFO, она выполняется, но когда делаешь SelectObject(cdc,bmp), выкидывается ошибка "Недостаточно памяти". И это при моём гигабайте!!!  smile 
Ну да ладно, главное разобрался и с CreateDIBSection, и с CreateCompatibleBitmap.
Теперь остался только один вопрос:
Какая разница между этими двумя функциями. Просто более широкие параметры настройки у первой? И всё? А остальное: читать, писать в созданные области памяти можно абсолютно одинаково. Так?

И да, книжку по GDI (ну и ещё чему интересному) не порекомендуете?

Это сообщение отредактировал(а) Arks - 20.9.2007, 07:48
PM MAIL ICQ Skype MSN   Вверх
Mihhail
Дата 20.9.2007, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Arks @  20.9.2007,  11:46 Найти цитируемый пост)
Какая разница между этими двумя функциями. Просто более широкие параметры настройки у первой? И всё? А остальное: читать, писать в созданные области памяти можно абсолютно одинаково. Так?

Да, не имеет значения какой функцией создавать область вывода. Просто CreateCompatibleBitmap использует настройки палитры и глубины цвта указанного контекста (в нашем случае экранные).
В чём особенность CreateDIBSection - она даёт указатель на начало растровых данных, тот самый ppvBits, т.е. возможно менять значения байтов отдельных пикселей и их составляющих (RGB) непосредственно в памяти, что во много раз быстрее чем при вызове функций рисования, но мение удобно. К тому же с помощью этой функции есть возможность считывать изображения из файла.

Цитата(Arks @  20.9.2007,  11:46 Найти цитируемый пост)
И да, книжку по GDI (ну и ещё чему интересному) не порекомендуете?

Моя любимая и единственная книжка по программированию - это справочная система Borland C++Builder 6!  smile 
Шучу конечно, но так что бы где-то толково и полностью о GDI было написано я лично не встречал таких книг.

PM MAIL WWW   Вверх
Arks
Дата 20.9.2007, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Всё ясно.
Спасибо вам за помощь.
PM MAIL ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0965 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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