почему CreateDIBSection() не работает с certian BITMAINFO?

Я пытаюсь использовать CreateDIBSection.

Проблема:

В Windows XP пробовал вызывать CreateDIBSection, возвращает NULL и GetLastError = 0

Когда я пытаюсь изменить разрешение экрана, например, на 2048 x 1536, он возвращает правильное значение.

Я проверил, что эта функция имеет некоторое отношение к nMemSize (не обязательно маленькому числу).

Вопрос:

Есть ли какой-либо гарантированный способ гарантировать, что CreateDIBSection возвращает правильное значение?

nScreenWidth = 1024;
nScreenHeight= 768;
 = nScreenWidth*nScreenHeight*3*7
HDC hdc = ::GetDC(hWnd);
m_hBmpMapFile = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMemSize, NULL);

BITMAPINFO bmpInfo = {0};
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = nScreenWidth;
bmpInfo.bmiHeader.biHeight = nScreenHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpInfo.bmiHeader.biCompression = 0;
bmpInfo.bmiHeader.biSizeImage = nMemSize;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 0;
bmpInfo.bmiHeader.biClrImportant = 0;
bmpInfo.bmiColors[0].rgbBlue = 204;
bmpInfo.bmiColors[0].rgbGreen = 204;
bmpInfo.bmiColors[0].rgbRed = 204;
bmpInfo.bmiColors[0].rgbReserved = 0;
PVOID pvBits;

m_hBmpAllWstDskWallpaper = ::CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pvBits, m_hBmpMapFile, 0); 

person yyy    schedule 18.01.2011    source источник
comment
Ну не понятно почему не получается. Я думаю, что ваш вопрос действительно должен быть, почему CreateDIBSection терпит неудачу?. Если вы можете получить ответ на этот вопрос, тогда вы сможете решить свою настоящую проблему.   -  person David Heffernan    schedule 18.01.2011
comment
хорошо, я изменил его. Я думаю, что настоящая проблема заключается в том, что CreateDIBSection не работает, когда nMemSize изменяется на номер сертификата. иногда это не удается, скажем, 10000, но когда вы меняете nMemsize на большее 20000, это удается.   -  person yyy    schedule 18.01.2011
comment
@yyy: опубликуйте все поля bmpinfo.bmiHeader. Какие ценности вы им приписываете?   -  person Nawaz    schedule 18.01.2011
comment
Пожалуйста, предоставьте полный код. Нам было бы гораздо проще сказать (или догадаться), где может быть проблема. И почему это * 7 в уравнении nMemSize?   -  person detunized    schedule 18.01.2011
comment
извините, я только что отредактировал. *3 для байтов RGB, *7 для 7-кратного размера экрана. Я делаю большой горизонтальный панорамный экран.   -  person yyy    schedule 18.01.2011
comment
Отлично работает с моей машиной с Windows 7. Может ли это быть другой сбой API-функции? Пробовали ли вы вызывать GetLastError после других вызовов API?   -  person MW_dev    schedule 18.01.2011
comment
Всегда ли nScreenWidth делится на 4 без остатка?   -  person Mark Ransom    schedule 20.02.2012


Ответы (1)


Я подозреваю, что проблема может заключаться в том разделе кода, который вы не включили (в троеточиях...). Итак, я рекомендую:

  • Убедитесь, что контекст вашего устройства действителен
  • нулевая память
  • Добавьте размер конструкции
  • И размеры растрового изображения
  • Переместите вызовы GetLastError, чтобы убедиться, что контекст устройства действителен (возможно, более ранний вызов API не работает)

Код ниже, кажется, работает после того, как я добавил приведенные выше рекомендации, надеюсь, это поможет:

        HDC hdc = ::GetDC(hWnd); 
        int nScreenWidth = 1024; 
        int nScreenHeight= 768; 
        int nMemSize = nScreenWidth*nScreenHeight*3*7;
        HANDLE m_hBmpMapFile = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nMemSize, NULL); 
        BITMAPINFO bmpInfo; 
        //clear the memory
        ZeroMemory(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER));
        //struct size
        bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
        //dimensions
        bmpInfo.bmiHeader.biWidth = nScreenWidth;
        bmpInfo.bmiHeader.biHeight = nScreenHeight;
        bmpInfo.bmiHeader.biPlanes = 1; 
        bmpInfo.bmiHeader.biBitCount = 32; 
        bmpInfo.bmiHeader.biSizeImage=nMemSize; 
        void *pvBits = NULL;
        HANDLE m_hBmpAllWstDskWallpaper = ::CreateDIBSection(hdc, &bmpInfo, DIB_RGB_COLORS, &pvBits, m_hBmpMapFile, 0);
        int nError = ::GetLastError();      
person MW_dev    schedule 18.01.2011