Конференция "Начинающим" » Как создать HDC с конкретными параметрами, не указывая совместимо [D7, WinXP]
 
  • An a Student (06.12.16 09:18) [0]
    Я хочу создать новые HDC. С конкретными характеристиками. Собственно не понимаю вот чего...
    Планирую прикрепить к ним HBITMAP и рисовать на битмапах указывая эти контексты.
    Но как мне создать HDC для 32-битного битмапа? Функция CreateCompatibleDC требует образец, которого у меня нету. Можно передать ей NULL и тогда "будет создан контекст, совместимый с экраном монитора". Но чего если монитор настроен как 24-битный, или вовсе 256 цветов?
    Функция CreateDC хочет "имя драйвера" и "название устройства" (где мне их взять?), а характеристики указать вроде как негде.
    Есть ли способ просто создать DC и явно указать ему нужные характеристики? Не могу нагуглить, выдаёт только уже известные мне способы, которые видимо не подходят.
    А так же, есть ли ограничения на количество HDC, создаваемых приложением?
    Спасибо!
  • Dimka Maslov © (06.12.16 11:14) [1]
    Посмотри, как устроено создание контекста устройства в классе TBitmap. А лучше просто создай экземпляр TBitmap и забери у него значение Canvas.Handle
  • Pavia © (06.12.16 13:24) [2]

    > Я хочу создать новые HDC. С конкретными характеристиками.

    HDC - где D - это Device устройство.
    GDI - где D - это Device устройство.
    Хотите рисовать независимо рисуйте в памяти, ручками. (если что так ни писано в SDK от майрософта на Win 3.1)


    > Но как мне создать HDC для 32-битного битмапа?

    Вариант1. Взять 24 битный монитор с 32 битным экраном. Кое заявлен как требование в стандарте PC98. И такой экран является обязательным требованиям для Win Vista и страше.

    Вариант 2. Или отказаться от GDI и взять AggPas он позволит рисовать изображения прямо в памяти независимо от устройств.


    > А так же, есть ли ограничения на количество HDC, создаваемых
    > приложением?

    Да. Суммарно на все приложения ОС всего 65536 хэндлов. У меня сейчас 50 000 занято.  


    > Но чего если монитор настроен как 24-битный, или вовсе 256
    > цветов?

    К примеру тут рисуем ручками в памяти. А GDI только отображает.
    FillChar(p^,W*H*4, $FF); - 32 битное рисование. А GDI уже сам транслирует в 8, 24 или куда ему надо.

    procedure TForm1.Button1Click(Sender: TObject);
    var BI:TBitmapInfo;
    p:Pointer;
    bp:HBITMAP;
    DC,DCM:HDC;
    I,W,H:Integer;
    t1,t2:Int64;
    begin
    w:=1280;
    h:=1024;
    DC:=GetDC(0);
    BP:=CreateCompatibleBitmap(DC,W,H);
    DCM:=CreateCompatibleDC(DC);
    SelectObject(DCM, BP);

    FillChar(BI,SizeOf(BI),0);

    BI.bmiHeader.biSize:=sizeof(TBitmapInfo);
    BI.bmiHeader.biWidth:= w;
    BI.bmiHeader.biHeight:= H;
    BI.bmiHeader.biPlanes:= 1;
    BI.bmiHeader.biBitCount:= 32;
    BI.bmiHeader.biCompression:= BI_RGB;

    GetMem(p,W*H*4);
    FillChar(p^,W*H*4, $FF);
    t1:=gettickcount;
    for i:=0 to 1000-1 do
    begin
    SetDIBits(DCM,bp,0,H,p,BI,DIB_RGB_COLORS);
    BitBlt(DC,0,0,W,H, DCM,0,0,SRCCOPY);
    end;
    t2:=gettickcount;
    caption:=IntToStr(1000000 div(t2-t1));
    DeleteDC(DC);
    DeleteDC(DCM);
    DeleteObject(BP);
    end;
  • An a Student (06.12.16 23:29) [3]
    > Посмотри, как устроено создание контекста устройства в классе TBitmap.

    Хорошо бы, да в моей лицензии исходников не предусмотрено...

    > Хотите рисовать независимо

    Я не хочу независимо, я хочу подробно изучить использование GDI32.

    > Взять 24 битный монитор с 32 битным экраном.

    Это как так эдак?
    Винда ж в настройках задаёт параметры каким будет экран. Сама физическая конструкция не важна.

    > требованиям для Win Vista и страше

    У меня Win2000. Мне самоцель научиться писать GDI-код работающий от Win98 до XP.

    > Суммарно на все приложения ОС всего 65536 хэндлов.

    Стоп, что значит суммарно? Может на процесс? Если (теоретически) я займу 62`000, то винда грохнется что ли?
    Это поэтому всюду демки "создали, нарисовали, удалили"? А я думал создать что надо и хранить...

    > DC:=GetDC(0);
    > BP:=CreateCompatibleBitmap(DC,W,H);
    > DCM:=CreateCompatibleDC(DC);


    Ну вот, вы сделали CreateCompatible* - а вы знаете какой он конкретно у экрана? И какой у вас вышел? Если он 256 цветов как вы это поймёте/учтёте?
    И зачем у вас DCM вообще создаётся? *DIBits вроде и на DC будет такой же результат давать, и в данном примере судя по всему так быстрее выйдет.
  • Pavia © (07.12.16 00:10) [4]

    > Винда ж в настройках задаёт параметры каким будет экран.
    >  Сама физическая конструкция не важна.

    Там всё взаимосвязано. Винда скрывает не поддерживаемые режимы. Поддерживаемые режимы определяет видео карта. По параметрам монитора.

    Это упрощённа, без учёта всяких драйверов которые могут по перехватить и по создавать виртуальных экранов и мониторов.  


    > Стоп, что значит суммарно? Может на процесс?

    Нет на ОС. Откройте диспетчер задач он показывает число используемых хэндлов.


    > Если (теоретически) я займу 62`000, то винда грохнется что
    > ли?

    Что это ей падать когда ещё 3000 в запасе есть? Вот когда дойдёт повиснет или грохнется.


    > Это поэтому всюду демки "создали, нарисовали, удалили"?
    > А я думал создать что надо и хранить...

    Так в справке всё написано.


    > Ну вот, вы сделали CreateCompatible* - а вы знаете какой
    > он конкретно у экрана? И какой у вас вышел? Если он 256
    > цветов как вы это поймёте/учтёте?

    А зачем учитывать? Характеристики экрана можно получить или HDC.
    https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd144877(v=vs.85).aspx


    > И зачем у вас DCM вообще создаётся?

    Что-бы GDI не переопределял число цветов у изображения. Иначе обработку буфера придётся писать под все форматы пикселя.
  • An a Student (07.12.16 08:50) [5]
    > Так в справке всё написано.

    Там написано что если создали - надо освободить. Это и так ясно.
    Но нет объяснений почему всюду создают и освобождают сотни раз в секунду. Это кажется нерациональным.

    > не переопределял число цветов

    Где об этом написано? И почему использование двух одинаковых DC должно помогать с этим?
    Либо ему не надо DCM и всё будет работать, либо это не поможет. Потому что DC и DCM одинакового типа, заранее нам неизвестного.
  • sniknik © (07.12.16 11:28) [6]
    Pavia ©   (07.12.16 00:10) [4]
    > повиснет или грохнется.
    да не, просто будет ошибки выдавать про законченность ресурса, а вот если прога не умеет их обрабатывать вот тогда она, и из-за нее возможно винда, грохнется.

    An a Student   (06.12.16 23:29) [3]
    > я хочу подробно изучить
    вот, сделай текстовый файл, с названием "run200.vbs" например и содержимым (ниже), и запусти, будет весело... в процессе смотри на доступные ресурсы в диспетчере задач.
    ExeName = "mspaint.exe"

    Set oShell = Wscript.CreateObject("WScript.Shell")
    FOR n=1 to 200
    oShell.Run(ExeName)
    NEXT

  • Игорь Шевченко © (07.12.16 12:52) [7]
    Повиснет.
  • An a Student (11.12.16 14:50) [8]
    гм... Просто я думаю зачем например при каждом OnPaint делается GetDC() + ReleaseDC()? При каждом. То есть вплоть до 10~20~30 раз в секунду.
    Разве не логично в OnCreate сделать один раз GetDC(), а в OnDestroy сделать один раз ReleaseDC()? Ну и при RecreateWnd делать ReleaseDC() + GetDC() разумеется.
    Это что типа как раз из-за того что "на все приложения"? Интересно, а в TBitmap чего также при каждом обращении делается заново...

    Насчёт скрипта vbs - если мне понадобится запустить кучу пэйнтов - я возьму CreateProsess(). =)

    И всё же я пока не услышал ответ на свой основной вопрос...
  • sniknik © (11.12.16 16:47) [9]
    > не услышал ответ на свой основной вопрос...
    42
  • Игорь Шевченко © (11.12.16 21:38) [10]

    > Просто я думаю зачем например при каждом OnPaint делается
    > GetDC() + ReleaseDC()?


    https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd183571(v=vs.85).aspx
 
Конференция "Начинающим" » Как создать HDC с конкретными параметрами, не указывая совместимо [D7, WinXP]
Есть новые Нет новых   [134430   +0][b:0][p:0.001]