ExtCreatePen и Windows 7 GDI - PullRequest
       20

ExtCreatePen и Windows 7 GDI

1 голос
/ 21 января 2010

Я создал перья DIBPATTERN с API ExtCreatePen для перьев пользовательских шаблонов.

Он успешно рисует нужные линии в Windows XP,

Но в Windows 7 (x64 для моего случая) он не рисует никаких линий; без изменений на экране.

(Другие просто созданные ручки, например CreatePen (PS_DOT, 1,0), работают.)

Я обнаружил, что вызов SetROP2 (hdc, R2_XORPEN) заставляет следующие вызовы API рисования линий рисовать что-то, но с помощью операции XOR. Я не хочу рисовать XOR.

Вот мой код для создания пера. В Windows XP проблем нет:

LOGBRUSH lb;
lb.lbStyle = BS_DIBPATTERN;
lb.lbColor = DIB_RGB_COLORS;
int cb = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 2 + 8*4; 
HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, cb);                
BITMAPINFO* pbmi = (BITMAPINFO*) GlobalLock(hg);
ZeroMemory(pbmi, cb);
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
pbmi->bmiHeader.biWidth = 8; 
pbmi->bmiHeader.biHeight = 8; 
pbmi->bmiHeader.biPlanes = 1; 
pbmi->bmiHeader.biBitCount = 1; 
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 8;
pbmi->bmiHeader.biClrUsed = 2;
pbmi->bmiHeader.biClrImportant = 2;
pbmi->bmiColors[1].rgbBlue =
pbmi->bmiColors[1].rgbGreen =
pbmi->bmiColors[1].rgbRed = 0xFF;
DWORD* p = (DWORD*) &pbmi->bmiColors[2];
for(int k=0; k<8; k++) *p++ = patterns[k];
GlobalUnlock(hg);
lb.lbHatch = (LONG) hg;
s_aSelectionPens[i] = ExtCreatePen(PS_GEOMETRIC, 1, &lb, 0, NULL);
ASSERT(s_aSelectionPens[i]); // success on both XP and Win7
GlobalFree(hg);

Это ошибка только на моем ПК? Пожалуйста, проверьте эту проблему. Спасибо.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2010

Итак, вы создаете черно-белое (монохромное) растровое изображение 8x8 в качестве DIB, а затем используете его для создания пера. Я не вижу ничего плохого в этом коде. это определенно похоже на ошибку Windows, но может быть обходной путь.

Попробуйте установить

pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;

В этом контексте установка значений на 0 должна означать то же самое, что и установка их на 2, но 0 - более стандартное поведение для ситуаций, когда вы используете полную палитру. Вам все еще нужны две записи в вашей палитре, 0 означает «полный размер на основе biBitCount».

Кроме того, каждая запись палитры является RGBQUAD, что означает, что есть место для альфы, и ваша альфа установлена ​​в 0, что должно игнорироваться, но, возможно, это не так. поэтому попробуйте установить старший байт ваших двух записей палитры на 0xFF или 0x80.

Наконец, возможно, что ваша палитра полностью игнорируется, и Windows использует BkMode, BkColor и TextColor целевого DC для всего, поэтому вам нужно убедиться, что они установлены в значения, которые вы видите.

Я предполагаю, что это как-то связано с альфа-прозрачностью, поскольку GDI полностью игнорирует альфа, а Aero - нет.

0 голосов
/ 19 июня 2010

Это известная ошибка в Windows 7 GDI, но, к счастью, Microsoft признает ее.

http://social.technet.microsoft.com/Forums/en-US/w7itproappcompat/thread/a70ab0d5-e404-4e5e-b510-892b0094caa3

-Noel

0 голосов
/ 15 февраля 2010

Признаюсь, я был сомнителен как первый, но я скомпилировал и запустил вашу программу, и она действительно не в состоянии нарисовать вторую строку в Windows 7, купить только в режиме аэро

При переключении в основной или классический режим Windows все четыре линии отображаются, как и ожидалось.

Я могу только предположить, что это какое-то плохое взаимодействие с вашим пером, и новый способ аэрорежима реализует вызовы GDI. Кажется, это может быть ошибка Microsoft, возможно, вы можете разместить этот вопрос на одной из их досок объявлений?

...