-
[68] Дмитрий С (21.03.08 23:23) А вот кстати вопрос, почему буферизация называется двойной. Буфер ведь один:) [69] oxffff © (21.03.08 23:25) > Буфер ведь один:) Как один? MemBitmap и Bitmap окна. Получается два. Ты что не знал? [70] Дмитрий С (21.03.08 23:29) Ты рисуешь в битмэп, а затем выводишь его в конву окна. Этот битмэп и есть - буфер. Что по твоему еще тут буфер? > Bitmap окна Очень смешно:) [71] oxffff © (21.03.08 23:37) Узнай новое. A DC is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations. Unlike most of the structures, an application never has direct access to the DC; instead, it operates on the structure indirectly by calling various functions. ( Bitmaps can be selected for memory DCs only, and for only one DC at a time.) См. SelectObject. [73] Дмитрий С (21.03.08 23:46) А DC - это по твоему окно? :) [77] oxffff © (22.03.08 00:15) DC - это то что ты видишь в окне. И то что ты утверждаешь, что у DC нет буфера более чем странно. Читай про Display Device Contexts There are three types of DCs for video displays: Class Common Private [78] oxffff © (22.03.08 00:27) Шах и мат. :) GDI Technical Articles GDI Objects by Ron Gery Using an output device context (DC) creates a bitmap with the native color format; using a memory DC creates a bitmap that matches the color format of the bitmap currently selected into that DC. (The DC’s color format changes based on the color format of the currently selected bitmap.) [79] Дмитрий С (22.03.08 00:32) DC - это то, посредством чего я рисую на окне, экране, принтере или битмапе, но не то что я вижу. Оно даже и называется Контекст устройства. То что я вижу - это содержимое видеопамяти (ну... в общем случае). [80] oxffff © (22.03.08 00:36) Скажи зачем в каждом DC есть Bitmap? Это буфер на котором ты рисуешь. И возвращаясь к твоему утверждению, почему буфер один для DoubleBuff. У тебя два DC, и два буфера. Убедил? [81] Дмитрий С (22.03.08 00:41) > Using an output device context (DC) creates a bitmap with > the native color format; using a memory DC creates a bitmap > that matches the color format of the bitmap currently selected > into that DC. (The DC’s color format changes based on the > color format of the currently selected bitmap.) Это выдернуто из контекста параграфа про создание битмэпов. А мы говорим про буферизацию. Для отображения, к примеру, еллипса в, к примеру, окне, между вызовом функции ellipse и появлением, буфер, в виде битмепа, не создается. За исклчением, может быть, окон обработанных функцией updateLayeredWindow. [82] Дмитрий С (22.03.08 00:45) > Скажи зачем в каждом DC есть Bitmap? > Это буфер на котором ты рисуешь. В каждом DC нет BitMap-а. Блин, не кидайся цитатами из спавки, просто почитай. [83] oxffff © (22.03.08 00:51) > Для отображения, к примеру, еллипса в, к примеру, окне, > между вызовом функции ellipse и появлением, буфер, в виде > битмепа, не создается. За исклчением, может быть, окон обработанных > функцией updateLayeredWindow. > Защищаться, похоже, ты можешь только кулаками:) > > Заканчиваем флуд... Подожди. Давай уж выясним подробности. Вопрос первый. Покрепить свои слова выдержкой из MSDN не соизволишь. >буфер, в виде битмепа, не создается. Я тебе еще раз повторяю цитатами из MSDN Using an output device context (DC) читай дословно Display Device Contexts creates a bitmap with the native color format; using a memory DC creates a bitmap that matches the color format of the bitmap currently selected into that DC. (The DC’s color format changes based on the color format of the currently selected bitmap.) Если ты хочешь сказать, что у DC окна нет битмапа (буфера) и весь вывод напрямую производиться в видеопамять (или она mapнута на RAM). То скажи зачем в Microsoft придумали DIRECTDRAW, если по твоим словам все напрямую. Я готов продолжить с тобой диалог, если с твоей стороны будут конкретные факты c документации Microsoft, а так с твоей стороны действительно треп уж извини. [85] Дмитрий С (22.03.08 00:59) > oxffff © ты опять выдрал предложения из контекста. Лучше не цитировать ничего, чем то, что к тебе не относится. Вот тут сказано что такое ДЦ и для чего он... http://msdn2.microsoft.com/en-us/library/ms533227(VS.85).aspx [87] oxffff © (22.03.08 01:05) Ты по английски читать умеешь из своей ссылки. Там все написано. A DC is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations.
-
Надеюсь, здесь будет продолжение... Чтобы народ мог понять, что буфферов всетаки два, а не один.
-
у DC нету буфера. Если бы он был, система бы не посылала WM_PAINT окну всякий раз, когда меняется перекрытие окна другими окнами, за исключением, когда у перекрывающего окна установлен стиль CS_SAVEBITS
-
> То скажи зачем в Microsoft придумали DIRECTDRAW, если по > твоим словам все напрямую.
Ты тут всё узлом завязал. К тому-же Explorer начиная с Win98 работает через DirectDraw.
-
> К тому-же Explorer начиная с Win98 работает через DirectDraw.
Странно. Я в окне Explorer'а вижу стандартные оконные классы - SysListView32, SysTreeView32, Edit... кто из них научился работать через DirectDraw ?
-
Читая разное в сети у меня складывается впечатление, что Свойство DoubleBuffered создает эффект двойной буфферизации, хотя принцип несколько инной. В википедии, кста, есть статья.
-
Дмитрий С (22.03.08 11:53) [5]
Изначально двойная буферизация применялась для увеличения совокупного быстродействия, чтобы не ждать, когда завершится работа по чтению буфера.
-
> Игорь Шевченко © (22.03.08 12:03) [6]
То есть, два буфера, которые работают параллельно (т.е. выполняют одну и ту же функцию), но не друг за другом? Так?
-
Дмитрий С (22.03.08 12:05) [7]
Один буфер заполнился - передается на обработку, в это время необходимо ждать, пока он обработается. Чтобы не ждать, заполняется второй буфер, после этого они меняются местами - второй отдается на обработку, первый заполняется.
-
Ну все. Я так себе это и представлял. Спасибо:)
-
Кстати, hint: GDI тоже буферизует операции отрисовки. В системе существует очередь операций GDI
И вообще - читать Фень Юаня - программирование графики в Windows.
-
> Странно. Я в окне Explorer'а вижу стандартные оконные классы > - SysListView32, SysTreeView32, Edit...кто из них научился > работать через DirectDraw ?
GDI - читал где-то, году так в 98-м.
-
tesseract © (22.03.08 12:08) [11]
GDI практически всегда работает через те же дырки, что и DirectDraw - оно по другому не умеет просто :)
-
> GDI практически всегда работает через те же дырки, что и > DirectDraw - оно по другому не умеет просто :)
Ну немного не так выразился. А ComCtrs - он к GDI типо не относиться ?
-
tesseract © (22.03.08 12:22) [13]
> А ComCtrs - он к GDI типо не относиться ?
Не, не относится.
-
> Не, не относится.
Гм. после 4-й версии думал что ComCtrls поддеерживает аппаратную отрисовку. 6-я тем более должна держать. Иначе XP томозил бы как win3.11 при отрисовке без аппаратной акселерации. (была такая фича у старых видеокарт - Windows Accelerator, иконки отрисовывал быстрее)
-
> Игорь Шевченко © (22.03.08 11:29) [2] > у DC нету буфера. Если бы он был, система бы не посылала > WM_PAINT окну всякий раз, когда меняется перекрытие окна > другими окнами, за исключением, когда у перекрывающего окна > установлен стиль CS_SAVEBITS
Да как же нету буфера. У него есть Bitmap. На котором вы рисуете. Далее этот битмат передается драйверу. вместе с областью отсечения.
-
> tesseract © (22.03.08 12:32) [15]
Это GDI использует аппаратное ускорение частично, а ComCtrls использует GDI. А причина тормозов win3.11 при рисовании в слабых процессорах тех времен.
-
> Да как же нету буфера. У него есть Bitmap. На котором вы > рисуете.
У кого есть Bitmap? У DC?
-
Читать по стили и типы DC
CS_OWNDC CS_SAVEBITS -
Common Device Contexts Common device contexts are display DCs maintained in a special cache by the system. Common device contexts are used in applications that perform infrequent drawing operations. Before the system returns the DC handle, it initializes the common device context with default objects, attributes, and modes. Any drawing operations performed by the application use these defaults unless one of the GDI functions is called to select a new object, change the attributes of an existing object, or select a new mode.
Because only a limited number of common device contexts exist, an application should release them after it has finished drawing. When the application releases a common device context, any changes to the default data are lost.
Private Device Contexts Private device contexts are display DCs that, unlike common device contexts, retain any changes to the default dataeven after an application releases them. Private device contexts are used in applications that perform numerous drawing operations such as computer-aided design (CAD) applications, desktop-publishing applications, drawing and painting applications, and so on. Private device contexts are not part of the system cache and therefore need not be released after use. The system automatically removes a private device context after the last window of that class has been destroyed.
An application creates a private device context by first specifying the CS_OWNDC window-class style when it initializes the style member of the WNDCLASS structure and calls the RegisterClass function. (For more information about window classes, see Window Classes.)
After creating a window with the CS_OWNDC style, an application can call the GetDC, GetDCEx, or BeginPaint function once to obtain a handle identifying a private device context. The application can continue using this handle (and the associated DC) until it deletes the window created with this class. Any changes to graphic objects and their attributes, or graphic modes are retained by the system until the window is deleted.
-
> У кого есть Bitmap? У DC?
Ты что читать не умеешь?
DC is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations.
-
> DVM © (22.03.08 14:01) [17] > > > tesseract © (22.03.08 12:32) [15] > > Это GDI использует аппаратное ускорение частично,
С этим я могу согласиться. Существует возможность использования ускорения за счет делегирования функциональности интерфейса GDI -> драйверу видеокарты, либо непосредственного отображения области видео вывода окна на область RAM. Но это уже исключение. При таком раскладе разницы между GDI и DirectDraw нет. К этому естественно все и идет. А если видеокарта не поддреживает то область вывода окна формируется в DC. и BITMAP просто передается драйверу вместе с CLIP областью.
-
> oxffff © (22.03.08 14:12) [20] > > > У кого есть Bitmap? У DC? > > > Ты что читать не умеешь?
В том то и дело что умею. Пока битмап не выбран в контекст его там нет.
-
> В том то и дело что умею. Пока битмап не выбран в контекст > его там нет.
В устройстве нет. В буфере есть. Или ты думаешь, что винда его не кэширует? Двойной буффер и есть в приложении. Один у системы второй у нас. Там на самом деле ещё и HAL лепту вносит.
-
tesseract © (22.03.08 15:21) [23]
> В устройстве нет. В буфере есть. Или ты думаешь, что винда > его не кэширует?
Кто куда кого кеширует ?
-
oxffff © (22.03.08 14:12) [20]
Эта...а у Device Context'а принтера тоже внутре битмап есть ? А у метафайла ?
-
> DVM © (22.03.08 14:55) [22] > > > oxffff © (22.03.08 14:12) [20] > > > > > У кого есть Bitmap? У DC? > > > > > > Ты что читать не умеешь? > > В том то и дело что умею. Пока битмап не выбран в контекст > его там нет.
Точно хорошо читаешь?
см. SelectObject
hgdiobj
(Bitmaps can be selected for memory device contexts only, and for only one device context at a time.)
Так что для остальных DC это сделать нельзя.
-
> Игорь Шевченко © (22.03.08 16:15) [25] > oxffff © (22.03.08 14:12) [20] > > Эта...а у Device Context'а принтера тоже внутре битмап есть > ? А у метафайла ?
А какое отношение имеет метафайл к DC?
>Device Context'а принтера тоже внутре битмап есть
Нет, а что окна выводятся на принтер?
-
> А какое отношение имеет метафайл к DC?
Я имею ввиду какое отношение имеет сериализация графических операций к непосредственному выводу?
-
> Эта...а у Device Context'а принтера тоже внутре битмап есть > ? А у метафайла ?
Эмм а при чем тут принтер? Вывод графики через драйвер устройства (vga.dll и т.п.) идет, а DC это абстрактный уровень... В MSDN же описано в About Device Contexts
-
oxffff © (22.03.08 21:15) [27] > А какое отношение имеет метафайл к DC?
Он (метафайл) его имеет. > > Нет, а что окна выводятся на принтер?
У принтера тоже есть DC В посте 20 ты написал: "Ты что читать не умеешь? DC is a structure that defines a set of graphic objects and their associated attributes, and the graphic modes that affect output. The graphic objects include a pen for line drawing, a brush for painting and filling, a bitmap for copying or scrolling parts of the screen, a palette for defining the set of available colors, a region for clipping and other operations, and a path for painting and drawing operations." Все эти объекты применимы как к DC окна, так и к DC принтера, метафайла и еще чего-нибудь, у чего есть DC. В связи с этим у меня вопрос, а что у принтера или метафайла внутре его DC тоже битмап имеется, на котором рисуют ? А если принтер PostScript, тогда как ? oxffff © (22.03.08 21:19) [28] > Я имею ввиду какое отношение имеет сериализация графических > операций к непосредственному выводу?
В системе есть очередь операций GDI. Про нее можно прочитать тут: http://msdn2.microsoft.com/en-us/library/ms534903(VS.85).aspx
-
> Игорь Шевченко © (22.03.08 11:29) [2] > у DC нету буфера.
У DC есть буффер. Другое дело, что у окна обычно нет постоянного DC (если только ты не указал OWNDC).
-
Nobody (23.03.08 01:17) [31]
> Другое дело, что у окна обычно нет постоянного DC (если > только ты не указал OWNDC).
А если я указал CS_OWNDC, то что я могу сделать с буфером ?
-
> > В связи с этим у меня вопрос, а что у принтера или метафайла > внутре его DC тоже битмап имеется, на котором рисуют ? А > если принтер PostScript, тогда как ?
Я Отвечаю на ваш вопрос
A printer DC is similar to a display DC in that it is an internal data structure that defines a set of graphic objects and their associated attributes and specifies the graphic modes that affect output. The graphic objects include a pen (for line drawing), a brush (for painting and filling), and a font (for text output).
Как видите про Bitmap ни слова.
А вы попробуйте качестве source для BitBlt указать DC принтера, а в качестве dest Window DC. Только не забудьте прочитать вот это
BitBlt returns an error if the source and destination device contexts represent different devices. To transfer data between DCs for different devices, convert the memory bitmap to a DIB by calling GetDIBits. To display the DIB to the second device, call SetDIBits or StretchDIBits.
А вы с какой целью упоминули про DC принтера?
-
oxffff © (23.03.08 16:07) [33] Если у DC окна есть битмап, на котором все нарисовано, очевидно не составит труда сделать из него BitBlt в другое окно, вне зависимости от того, видно ли исходное окно ? Давай сделаем простой пример: unit AppMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
PaintBox1: TPaintBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
function EnumWindowProc (Wnd: HWND; param: LPARAM): Integer; stdcall;
var
AClassName: array[0..255] of char;
begin
with TForm1(param) do
begin
GetClassName(Wnd, AClassName, SizeOf(AClassName));
ListBox1.Items.AddObject(AClassName, TObject(Wnd));
end;
Result := 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Wnd: HWND;
ADC: HDC;
begin
if ListBox1.ItemIndex > -1 then
begin
Wnd := HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]);
if IsWindow(Wnd) then
begin
ADC := GetWindowDC(Wnd);
try
with PaintBox1.ClientRect do
StretchBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left,
Bottom - Top,
ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
finally
ReleaseDC(Wnd, ADC);
end;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
EnumWindows(@EnumWindowProc, LPARAM(Self));
end;
end. И нарисуем из DC каждого окна его картинку.
-
> Давай сделаем простой пример:
Давайте вы прочитаете документацию для начала. :)
Если это Common Device Contexts. То вы ничего не увидите. Для начала надо заставить окно отрисоваться в DC. Либо использовать стиль CS_OWNDC.
Я в разговоре о Double buf разделяю мнение, что буфера действительно два. Один MемD, второй window DC. В каждом есть битмап, на котором вы рисуете. Далее этот битмап отправляется драйверу видеокарты который копирует содержимое в Front buffer видеокарты.
-
> Далее этот битмап отправляется драйверу видеокарты который > копирует содержимое в Front buffer видеокарты.
То есть получается три буффера.
MEM BITMAP -> WINDOW BITMAP -> VIDEO FRONT BUFFER.
-
oxffff © (23.03.08 16:55) [35] > Давайте вы прочитаете документацию для начала. :) > > Если это Common Device Contexts. То вы ничего не увидите. > > Для начала надо заставить окно отрисоваться в DC. > Либо использовать стиль CS_OWNDC.
Нет проблем, меняем: function EnumWindowProc (Wnd: HWND; param: LPARAM): Integer; stdcall;
var
AClassName: array[0..255] of char;
CS: DWORD;
begin
with TForm1(param) do
begin
GetClassName(Wnd, AClassName, SizeOf(AClassName));
CS := GetClassLong(Wnd, GCL_STYLE);
if (CS and (CS_OWNDC)) <> 0 then
ListBox1.Items.AddObject(AClassName, TObject(Wnd));
end;
Result := 1;
end;
-
Часть операция может выполняет видеокарта. см. GetDeviceCaps.
CC_CHORD Device can draw chord arcs. CC_CIRCLES Device can draw circles. CC_ELLIPSES Device can draw ellipses. CC_INTERIORS Device can draw interiors. CC_NONE Device does not support curves. CC_PIE Device can draw pie wedges. CC_ROUNDRECT Device can draw rounded rectangles. CC_STYLED Device can draw styled borders. CC_WIDE Device can draw wide borders. CC_WIDESTYLED Device can draw borders that are wide and styled.
и т.д.
А то что не может быть нарисовано силами видео карты, рисует Windows в в DC bitmap'e окна.
Это мое IMHO.
-
До кучи еще тестовое окно запустим: unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
protected
procedure CreateParams (var Params: TCreateparams); override;
end;
var
Form1: TForm1;
implementation
procedure TForm1.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;
end.
-
> Игорь Шевченко © (23.03.08 17:09) [39]
Снимайте значок МАСТЕРА и передавайте его мне. Убедитесь, что картинка есть.
Поправьте
with PaintBox1.ClientRect do StretchBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left, Bottom - Top, ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
на
with Memo1.ClientRect do StretchBlt(GETDC(Memo1.Handle), Left, Top, Right - Left, Bottom - Top, ADC, 0, 0, Right - Left, Bottom - Top, SRCCOPY);
-
oxffff © (23.03.08 17:24) [40]
А как же буфер, который в каждом DC ? Мой вариант тоже должен работать - ему ж без разницы. Кроме того, регулярно народ спрашивает, как ему получить изображение окна, если оно закрыто другими. В случае наличия буфера такой проблемы быть не должно, верно ?
-
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
ApplicationEvents1: TApplicationEvents;
procedure ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
private
public
end;
var
Form1: TForm1;
implementation
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if Msg.message = wm_paint then ListBox1.Items.Add(DateTimeToStr(Now));
end;
end. Этот пример в Висте дает неожиданный интересный результат.
-
oxffff © (23.03.08 17:24) [40]
Кстати, о чем мы вообще спорим ?
Вот из Borland'овской справки: "Double buffering reduces the amount of flicker when the control repaints, but is more memory intensive."
Если у DC есть свой буфер, откуда вообще flicker возникает ?
-
> А как же буфер, который в каждом DC ?
Common device con texts are display DCs maintained in a special cache by the system. Common device contexts are used in applications that perform infrequent drawing operations. Before the system returns the DC handle, it initializes the common device context with default objects, attributes, and modes. Any drawing operations performed by the application use these defaults unless one of the GDI functions is called to select a new object, change the attributes of an existing object, or select a new mode.
Because only a limited number of common device contexts exist, an application should release them after it has finished drawing. When the application releases a common device context, any changes to the default data are lost.
-
> Если у DC есть свой буфер, откуда вообще flicker возникает > ?
Если после каждой графической операции DC пересылать подвергнутый операции RECT в VIDEO FRONT Buffer, то будет вам тот же flip. Другое дело, что видеокарта может брать на себя часть операций поддерживаемых аппаратно, причем формировать изображение тоже в буфере возможно в своей области. Вообщем без DDK спецификации к видеодрайверу уже не обойтись. :)
>Кстати, о чем мы вообще спорим ?
Честно говоря общение куда свалилось не туда.
-
oxffff © (23.03.08 19:10) [44]
> When the application releases a common device context, any > changes to the default data are lost.
Ну и нафига такой буфер нужен ? :)
Что по-твоему получается - в оконной процедуре по BeginPaint или по GetDC получается общий DC из кэша, на нем чего-то рисуется функциями GDI (надо понимать, в буфер ? ), а после ReleaseDC весь этот буфер пропадает ?
А теперь смотри: В системе масса окон, количество DC (всех, не только общих), всяко меньше количества окон, как они с буферами-то справляются ? Особенно, когда куча потоков лезет за DC в кэш.
-
> Если у DC есть свой буфер, откуда вообще flicker возникает > ?
Вопрос в другом, а что если видеокарта не поддерживает часть GDI операций, тогда изображение будет сформировано средствами Windows в буфере и растр просто будет передан в front буфер.
-
> Если после каждой графической операции DC пересылать подвергнутый > операции RECT в VIDEO FRONT Buffer, то будет вам тот же > flip.
Ну да. Я об том же. Вот Борланд (и не только он), сделал возможность формировать изображение в памяти, чтобы потом его одним чохом пересылать в контекст устройства (независимо от аппаратной буферизации, буферизации в ядре, и т.п.)
-
oxffff © (23.03.08 19:22) [47]
> Вопрос в другом, а что если видеокарта не поддерживает часть > GDI операций, тогда изображение будет сформировано средствами > Windows в буфере и растр просто будет передан в front буфер. >
Собственно, по-другому просто нельзя. Разумеется, растр где-то формируется, это еще со времен Windows 3.1 в DDK подробно расписано.
Но из этого не следует, что свой буфер есть у каждого DC, об чем собственно, большевики неоднократно заявляли.
-
> А теперь смотри: В системе масса окон, количество DC (всех, > не только общих), всяко меньше количества окон, как они > с буферами-то справляются ?
Ничего не мешает Windows поступать очень просто, не слать WM_PAINT при отсутствии ресурса. Но тем менее почти 100% окон как раз и являются Common Device Contexts. Ведь работает же.
-
> а после ReleaseDC весь этот буфер пропадает ?
Почему пропадает? Вы делаете EraseBackground и вперед с новой песней.
-
> oxffff © (23.03.08 19:28) [51]
В смысле просто очищаете труды предудущей оконной процедуры и заполняете своим контенком
-
> Но из этого не следует, что свой буфер есть у каждого DC, > об чем собственно, большевики неоднократно заявляли.
Во всяком случае bitmap obj есть для display DC. Разговор начался ведь с этого.
-
oxffff © (23.03.08 19:26) [50]
> Ничего не мешает Windows поступать очень просто, > не слать WM_PAINT при отсутствии ресурса.
Он так не поступает. Он просто не знает в момент посылки WM_PAINT, есть ресурсы или нету, потому что WM_PAINT всегда асинхронно посылается, да еще в очереди находится с низким приоритетом.
> Но тем менее почти 100% окон как раз и являются Common Device > Contexts. > Ведь работает же.
Ну да, работает. Потому что операции обрабатываются сами по себе, формируя растр (с учетом всех отсечений), без буфера в каждом DC :)
Собственно, почти вся ядерная часть GDI занимается по преимуществу отсечениями.
-
нет у окна никаких встроенных битмапов по-умолчанию и точка.
-
> Eraser © (23.03.08 19:36) [55]
Ссылочку на документацию в студию.
-
> Ссылочку на документацию в студию.
Каку. документацию?? Сказано же: Нет и точка!
-
> Eraser © (23.03.08 19:36) [55] > нет у окна никаких встроенных битмапов по-умолчанию и точка. >
procedure TForm1.Button1Click(Sender: TObject); var Hobj:HGDIOBJ; HDC:Thandle; begin HDC:=GetDC(Handle); Hobj:=GetCurrentObject(HDC,OBJ_BITMAP); if Hobj<>0 then SHOWMESSAGE('ERASER садись. Двойка.'); ReleaseDC(Handle,HDC); end;
-
> > Он так не поступает. Он просто не знает в момент посылки > WM_PAINT, есть ресурсы или нету, потому что WM_PAINT всегда > асинхронно посылается, да еще в очереди находится с низким > приоритетом.
Ну не проблема это. :)
-
> без буфера в каждом DC :)
oxffff © (23.03.08 19:45) [58]
-
oxffff © (23.03.08 19:32) [53]
> Во всяком случае bitmap obj есть для display DC. Разговор > начался ведь с этого.
Про display dc разговора не было вообще. Был разговор про DC окна.
Что есть у Display DC - то совершенно другой случай.
Вот скажи, когда в моем и в твоем примере делался StrectBlt куда биты пересылались ? В буфер конкретного DC (формы в данном случае) или в буфер растра после всех отсечений ? А если бы часть окна, где расположен PaintBox была бы закрыта, куда бы биты пересылались (или не пересылались)
-
> Про display dc разговора не было вообще. Был разговор про > DC окна. >Что есть у Display DC - то совершенно другой случай.
А как же это? :)
Display Device Contexts An application obtains a display DC by calling the BeginPaint, GetDC, or GetDCEx function and identifying the window in which the corresponding output will appear. Typically, an application obtains a display DC only when it must draw in the client area. When the application is finished drawing, it must release the DC by calling the EndPaint or ReleaseDC function.
There are three types of DCs for video displays:
Class Common Private
-
> Вот скажи, когда в моем и в твоем примере делался StrectBlt > куда биты пересылались ? В буфер конкретного DC (формы в > данном случае) или в буфер растра после всех отсечений ? >
Это зависит от того, эмулирует ли Windows операции, и если ДА, то какие.
-
> oxffff
А если, к примеру, окно отображается через терминал RDP, то буферов еще больше? Все же, я думаю, что понятие DoubleBuffered VCL не включает в себя буферы системы.
-
> Игорь Шевченко © (23.03.08 19:52) [61]
Скажите если по вашему все операции GDI идут без буфера к видеопамять.
Зачем придумали DIRECTDRAW?
-
> А если, к примеру, окно отображается через терминал RDP, > то буферов еще больше?
см Common Device Contexts
-
oxffff © (23.03.08 19:57) [62]
Продолжим дальше ? var DC: HDC; HBM: HBitmap; Info: tagBITMAP; begin ..... HBM := GetCurrentObject(DC, OBJ_BITMAP); GetObject(HBM, Sizeof(Info), @Info); ShowMessageFmt('Bitmap is %d x %d', [Info.bmWidth, Info.bmHeight]); ... end;
oxffff © (23.03.08 19:57) [62]
> А как же это? :)
Давайте отличать DC, созданные по CreateDC ('DISPLAY', ...) и оконные. Дабы не было путаницы, договоримся, что Display dc - это то, что создается по CreateDC
-
> Игорь Шевченко © (23.03.08 19:52) [61]
и КАК ЖЕ [58]?
Один Буфер c рабочий стол или несколько, но он есть. Вы посмотрите внимательно на ваш пример с CS_OWNDC, можно скопировать даже больше, чем окно с CS_OWNDC.
-
> [64] Дмитрий С (23.03.08 20:02)
> А если, к примеру, окно отображается через терминал RDP, > то буферов еще больше?
ребята создавшие RDP проделали отличную работу в плане кэширования, вот там многое, даже почти все, действиетельно кэшируется.. подобие такого механизма реализовано и в моем продукте, но примитивнее. попробуйте отключить кэширования и посмотрите каким плачевным станет результат.
> oxffff ©
отвечу чуть позже.
-
oxffff © (23.03.08 20:00) [63] > Это зависит от того, эмулирует ли Windows операции, и если > ДА, то какие.
Хорошо, русть не StretchBlt, пусть BitBlt, которую операцию умеет каждый драйвер. Куда биты будут пересылаться в случае, когда часть окна закрыта и в случае, когда она открыта ? И почему при изменении перекрытия окна другими окнами Windows посылает WM_PAINT тому окну, часть которого стала видимой, если оно уже было отрисовано в DC (OWN_DC) ? unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
ListBox1: TListBox;
procedure WMPaint (var Message: TWMPaint); message WM_PAINT;
protected
procedure CreateParams (var Params: TCreateparams); override;
end;
var
Form1: TForm1;
implementation
procedure TForm1.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;
procedure TForm1.WMPaint(var Message: TWMPaint);
begin
ListBox1.Items.Add('WM_PAINT');
inherited;
end;
end. Если поверх этого окна перемещать другое, то видна последовательность WM_PAINT. Нафига их выдают ?
-
oxffff © (23.03.08 20:10) [68]
> и КАК ЖЕ [58]?
А ты посмотри, какие характеристики у этого BITMAP
-
> Игорь Шевченко © (23.03.08 20:07) [67] > oxffff © (23.03.08 19:57) [62] > > Продолжим дальше ? > var > DC: HDC; > HBM: HBitmap; > Info: tagBITMAP; > begin > ..... > HBM := GetCurrentObject(DC, OBJ_BITMAP); > GetObject(HBM, Sizeof(Info), @Info); > ShowMessageFmt('Bitmap is %d x %d', [Info.bmWidth, Info. > bmHeight]); > ... > end;
OK. Ваш код не работает. Только исправляйте свой код на
if GetObject(Hobj, Sizeof(Info), @Info)<>0 then ShowMessageFmt('Bitmap is %d x %d', [Info.bmWidth, Info.bmHeight]);
-
> Если поверх этого окна перемещать другое, то видна последовательность > WM_PAINT. > > Нафига их выдают ?
А что при установке CS_OWNDC семантика поведения окна меняется? Почему вы связываете вид DC и ОКНО?
-
> Куда биты будут пересылаться в случае, когда часть окна > закрыта и в случае, когда она открыта ?
А что насчет CLIP RECT и regions?
-
Игорь Шевченко © (23.03.08 20:14) [71]
Сформулируйте точно вашу точку зрения. Как происходит работа GDI словами.
-
oxffff © (23.03.08 20:15) [72]
> OK. Ваш код не работает.
Э...а почему ? :) Вроде как битмап вынутый из DC.. (И действительно, битмап, проверено. Только вот вызов GetObject говорит A call to OS function failed)
oxffff © (23.03.08 20:20) [73]
> А что при установке CS_OWNDC семантика поведения окна меняется?
Так рисовать-то по твоей логике не надо. При CS_SAVEBITS, например, рисование меняется.
oxffff © (23.03.08 20:22) [74]
> А что насчет CLIP RECT и regions?
так они на что действуют-то ? На буфер DC или на буфер растра ?
-
oxffff © (23.03.08 20:24) [75]
> Сформулируйте точно вашу точку зрения. > Как происходит работа GDI словами.
Это хорошая просьба, боюсь, что для ответа на нее у меня не хватит ни знаний, ни времени, ни места на форуме.
Но в двух словах. если говорить о DC и об окнах, то буфер есть у растра, весьма вероятно, что физически оно живет у того самого DC, который по CreateDC('DISPLAY') создается. Все оконные DC представляют "окна" (пардон за тавтологию) в этот буфер, с границами, определямыми регионами отсечения.
-
> [58] oxffff © (23.03.08 19:45)
ну привязан какой-то битмап к контексту для непонятных целей и что дальше, это не значит, что в этом битмапе хранится картинка окна. http://img201.imageshack.us/my.php?image=compatabedcec7.gif (с) Фэнь Юань. вообще очень советую почитать 5 главу этой книги, там все подробно описано.
-
> ну привязан какой-то битмап к контексту для непонятных целей > и что дальше, это не значит, что в этом битмапе хранится > картинка окна.
А для каких целей он нужен? И что говорит Фэнь Юань?
-
> [79] oxffff © (23.03.08 21:33)
вот у него и поинтересуйтесь ) вот чего он не содержит, так это картинки с изображением окна. Ну не кэширует виндовз это и все тут.. на этом уровне абстракции по крайней мере, уверен, что на более низком уровне растры кэшируются графической подсистемой, но не здесь.
-
oxffff © (23.03.08 21:33) [79] Кстати, еще: Та же программа с небольшими изменениями, перечисляющая окна и пытающаяся вывести кусок с DC function EnumWindowProc (Wnd: HWND; param: LPARAM): Integer; stdcall;
var
AClassName: array[0..255] of char;
CS: DWORD;
begin
with TForm1(param) do
begin
GetClassName(Wnd, AClassName, SizeOf(AClassName));
CS := GetClassLong(Wnd, GCL_STYLE);
if (CS and (CS_OWNDC or CS_CLASSDC)) <> 0 then
ListBox1.Items.AddObject(AClassName, TObject(Wnd));
end;
Result := 1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Wnd: HWND;
ADC: HDC;
begin
if ListBox1.ItemIndex > -1 then
begin
Wnd := HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]);
if IsWindow(Wnd) then
begin
ADC := GetDC(Wnd);
try
with PaintBox1.ClientRect do
BitBlt(PaintBox1.Canvas.Handle, Left, Top, Right - Left,
Bottom - Top,
ADC, 0, 0, SRCCOPY);
finally
ReleaseDC(Wnd, ADC);
end;
end;
end;
end; У меня в ListBox три окна - ConsoleWindowClass от Far, MsoCommandBarPopup от Help по Delphi 2006 и ConsoleWindowClass от Apache, запущенного в консоли. Окно FAR не полноэкранное и перекрыто нижним краем окна программы. При нажатии на кнопку в PaintBox рисуется как часть окна Far, так и краешек окна программы, которым перекрыто окно Far. Меня это приводит к выводу о том, что буфер - он для растра, а не для каждого DC :) На этой оптимистической ноте закончим дискуссию ?
-
Попытаюсь подвести итог: Большинство операций рисования GDI вызывает обновление буфера растра. В зависимости от возможностей драйвера видеокарты, эти операции обновления отдаются либо драйверу напрямую, чтобы рисование выполнялось с использованием процессора видеокарты, либо GDI рисует по своим алгоритмам, используя процессор собственно компьютера и пересылает сформированное изображение в видеопамять. При установленном свойстве DoubleBuffered все рисование с точки зрения GDI выполняется одной операцией BitBlt, поэтому буфер растра обновляется один раз и результаты промежуточных операций на экране не мелькают.
-
Сохраню-ка я эту веточку для повышения образованности. Опять же много пользительных ссылок приведено... :-)
-
> [77] Игорь Шевченко © (23.03.08 20:38)
> Но в двух словах. если говорить о DC и об окнах, то буфер > есть у растра, весьма вероятно, что физически оно живет > у того самого DC, который по CreateDC('DISPLAY') создается. > Все оконные DC представляют "окна" (пардон за тавтологию) > в этот буфер, с границами, определямыми регионами отсечения.
Фэнь с вами согласен. Вероятно вы достаточно четко представляете себе отличия между контекстом устройства, связанным с конкретным окном, и контекстом, созданным функцией CreateDC. Главное отличие заключается в том, что к числу атрибутов первого относится прямоугольник вывода, являющийся подмножеством поверхности устройства, и объединенный видимый регион, который строится с учетом таких факторов, как регион окна, отсечение соседних и дочерних окон, видимых частей и обновляемого региона окна.
-
> Eraser © (23.03.08 21:37) [80] > > [79] oxffff © (23.03.08 21:33) > > вот у него и поинтересуйтесь ) > вот чего он не содержит, так это картинки с изображением > окна. Ну не кэширует виндовз это и все тут.. на этом уровне > абстракции по крайней мере, уверен, что на более низком > уровне растры кэшируются графической подсистемой, но не > здесь.
читать про Private Device Contexts и их отличие от Common Device Contexts.
-
> Меня это приводит к выводу о том, что буфер - он для растра, > а не для каждого DC :) > > На этой оптимистической ноте закончим дискуссию ?
Так я вам об этом выше написал. см. oxffff © (23.03.08 20:10) [68]
Но разговор был о том, есть некий DC SHARED растр, пусть он будет большой и разделяемый не суть важно.
Важно, что есть буфер который -> копируется в видепамять.
-
> Игорь Шевченко © (23.03.08 22:01) [82]
Именно это мнение я и разделяю. Поэтому при double buf буфферов может быть 2 и 3 с учетом front buf video.
-
> [85] oxffff © (23.03.08 22:09)
ну есть отличие, только поясните, какое это отношение имеет к теме, в частности, двойной буфферизации? что-то я не уловил момент..
-
> Eraser © (23.03.08 22:16) [88]
[37] [39] [40]
-
> [89] oxffff © (23.03.08 22:21)
вы не путаете кэширование gdi операций с кэшированием готовых растров? к слову в висте реализовали системный механизм растровой буфферизации, который успешно применяется в CDS2007, см. BeginBufferedPaint.
-
> Eraser © (23.03.08 22:29) [90]
Разговор у нас о DC и DC bitmap. Я вас не понял.
-
Честно говоря я думал, что под Device (в DC) подразумевается некое устройство (экран, окно, принтер, битмэп, метафайл) для возможности универсально "рисовать" на них. Иначе говоря, я думал, что bitmap в данном случае - лишь один из вариантов того, на чем можно рисовать с помощью DC. И, честно говоря, ранее меня не смущало, что битмэп привязывается к ДЦ с помощью функции SelectObject. Поправьте меня, если я не прав.
-
to Eraser
Offtop
BeginBufferedPaint
Ну насколько я понял назначение этой функции в том, чтобы обеспечить предварительную отрисовку содержимого в буфере видеокарты, а поскольку скорее всего все операции будут аппаратно поддержаны то сократится количество пересылок RAM -> VIDEO RAM. Что хорошо скажется на производительности.
Наш разговор был не об этом. :)
-
> [89] oxffff © (23.03.08 22:21)
> [37] [39] [40]
не пойму в чем "фишка" этого примера? ведь он только доказывает, то, что уже несколько раз проверял Игорь - копируется только то, что видимо. вот моя модификация
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Memo1: TMemo;
Button2: TButton;
procedure Button2Click(Sender: TObject);
protected
procedure CreateParams (var Params: TCreateparams); override;
private
public
end;
var
Form2: TForm2;
implementation
procedure TForm2.Button2Click(Sender: TObject);
const
WindowName = 'DMClient';
var
WindowRect: TRect;
hWnd: THandle;
begin
hWnd := FindWindow(nil, WindowName);
GetWindowRect(hWnd, WindowRect);
StretchBlt(GetDC(Memo1.Handle), 0, 0, Memo1.Width,
Memo1.Height,
GetDC(hWnd),
Memo1.Left, Memo1.Top, Memo1.Width,
Memo1.Height, SRCCOPY);
end;
procedure TForm2.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;
end.
окно DMClient'а видно только если оно на видимо и только те части, которые не скрыты другими окнами, ч.т.д. > BeginBufferedPaint > > Ну насколько я понял назначение этой функции в том, чтобы > обеспечить предварительную отрисовку содержимого в буфере > видеокарты, а поскольку скорее всего все операции будут > аппаратно поддержаны то сократится количество пересылок > RAM -> VIDEO RAM.
думаю да, реализация этой функции не многим отличается от того, что реализовано в VCL для более старых версий системы. Там вроде можно указать какой именно тип битмапа применять для кэширования, к примеру BPBF_DIB или BPBF_COMPATIBLEBITMAP.
-
> [92] Дмитрий С (23.03.08 22:38)
все правильно, контекст устройство это инструмент для рисования, а не холст. Холст (битмап) к нему можно привязать, но не ко всякому контексту, а только в compatable... BeginBufferedPaint позволяет обойти это ограничение, но только благодаря своим механихмам и для целей буфферизации, хотя возможно как то и можно добраться до внутреннего буффера, используемого этой функцией.
-
Кстати, то что оконный DC представляет собой дырку в общий DC объясняет и то, что в оконный DC нельзя выбрать BITMAP - а чего с ним потом делать, с выбранным BITMAP'ом ? :)
oxffff © (23.03.08 22:13) [86]
> Важно, что есть буфер который -> копируется в видепамять.
Или не копируется - какой смысл занимать центральный процессор рисованием в этом буфере, если процессор видеокарты поддерживает массу операций GDI ?
Когда GDI (внутри ядра) уже посчитал отсечения и решил, что нужно вызывать драйвер для рисования, он вызывает одну из известных функций. При инициализации видеоподсистемы драйвер видеокарты записывает в адреса этих известных функций те, которые он поддерживает. Которые не поддерживает, остаются для реализации алгоритмов GDI средствами центрального процессора. Фэнь Юань про этот процесс пишет более подробно.
Так вот - если драйвер не чего-то поддерживает, то буфер растра будет и GDI будет на нем рисовать и отсылать драйверу в виде внутренней BitBlt - это вроде все поддерживают. А если драйвер поддерживает какие-то операции GDI, то и буфера растра не будет - все рисование будет выполняться видеокартой.
-
> вот моя модификация
А что DMClient со стилем CS_OWNDC? Перечитай еще раз внимательно. :)
-
> Игорь Шевченко © (23.03.08 23:03) [96]
Это то понятно. Меня больше интересует вопрос более серьезный. А как быть если часть операций поддерживается, а часть нет. Часть операций видеокартой в VIDEO буфере, а часть в RAM буфере, Как потом смешивать результаты? :)))))))
-
> [97] oxffff © (23.03.08 23:05)
пардон, моя вина.. невнимательность, но суть дела это не поменяло.. даже если заменить WindowName = 'DMClient'; на WindowName = 'Form2'; эффект тот же - скрытая часть окна не копируется.
-
> oxffff © (23.03.08 23:08) [98]
Или делается копия в этом случае в RAM <--> VIDEO RAM.
-
oxffff © (23.03.08 23:08) [98]
> А как быть если часть операций поддерживается, а часть нет. > > Часть операций видеокартой в VIDEO буфере, а часть в RAM > буфере, > Как потом смешивать результаты? :)))))))
То, что не поддерживается, рисуется в буфере растра, потом они смешиваются. Адаптером.
-
> Игорь Шевченко © (23.03.08 23:15) [101]
Увы это можно сделать только для части операций. Операции могут иметь зависимости. :)
-
> Eraser © (23.03.08 23:10) [99] > > [97] oxffff © (23.03.08 23:05) > > пардон, моя вина.. невнимательность, но суть дела это не > поменяло.. даже если заменить WindowName = 'DMClient'; на > WindowName = 'Form2'; эффект тот же - скрытая часть окна > не копируется.
Однако если свернуть окно, то копируется начиная с несвернутого положения. Однако по данному примеру нельзя сделать вывод о количестве буферов или их отсутствии до попадания в front video buf.
-
oxffff © (23.03.08 23:23) [102]
> Увы это можно сделать только для части операций. > Операции могут иметь зависимости. :)
GDI тоже не дураки писали и о зависимостях представляют. Очевидно, что если нечто имеет зависимости и это нечто поддерживается аппаратно, а зависимости нет, то выбор делается в пользу целостности. Кроме того, набор функций, которые определяет драйвер, составлялся разработчиками GDI, поэтому зависимости они постарались исключить.
-
oxffff © (23.03.08 23:27) [103]
> Однако если свернуть окно, то копируется начиная с несвернутого > положения.
Что подтверждает тезис о том, что DC окна является дыркой в DC экрана. Правда, копируется то, что в данный момент видно с этого несвернутого положения. То есть, с того прямоугольника (или региона), который отсекает часть от общего экрана для DC окна.
-
> [103] oxffff © (23.03.08 23:27)
> Однако если свернуть окно, то копируется начиная с несвернутого > положения.
у меня копируется опять пустое место. вот модифицированный пример
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm2 = class(TForm)
Memo1: TMemo;
Button2: TButton;
Label1: TLabel;
Edit1: TEdit;
Timer1: TTimer;
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
protected
procedure CreateParams (var Params: TCreateparams); override;
private
public
end;
var
Form2: TForm2;
implementation
procedure TForm2.Button2Click(Sender: TObject);
begin
Timer1.Enabled := True;
end;
procedure TForm2.CreateParams(var Params: TCreateparams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_OWNDC;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
const
WindowName = 'Form2';
var
hWnd: THandle;
bmp: TBitmap;
begin
Beep;
Timer1.Enabled := False;
hWnd := FindWindow(nil, WindowName);
bmp := TBitmap.Create;
try
bmp.Width := Width;
bmp.Height := Height;
StretchBlt(bmp.Canvas.Handle, 0, 0, Memo1.Width,
Memo1.Height,
GetDC(hWnd),
0, 0, Memo1.Width,
Memo1.Height, SRCCOPY);
bmp.SaveToFile('test.bmp');
finally
bmp.Free;
end;
end;
end.
> Однако по данному примеру нельзя сделать вывод о количестве > буферов или их отсутствии до попадания в front video buf.
нет у DC окна никаких буфферов.
-
Ну и спор у вас :) Даже если где-то система что-то и буферизует, то на кой ляд программисту gdi об этом знать? Если содержимое окна надо каждый раз перерисовывать, значит нет буфера :) Если буфер есть, то на кой хрен мы каждый раз перерисовывем? :)
-
Пора кому-то браться за книжку "О чём спорят на форумах по Delphi".... Я из этой ветки массу новых знаний почерпнул!!!!
-
> 31512 (24.03.08 07:52) [108]
У Фень Юаня то же самое все гораздо более строго и подробно расписано. Правда без учета висты пока. А здесь спор не ради истины, а ради самого спора скорее.
-
> нет у DC окна никаких буфферов.
Игорь Шевченко © (23.03.08 22:01) [82]
-
oxffff © (24.03.08 13:34) [110]
Ну все равно ведь нету :) у DC окна...
-
> Игорь Шевченко © (24.03.08 14:25) [111]
Как нету?
А как же HBM := GetCurrentObject(DC, OBJ_BITMAP);?
Ведь растр есть. И нет гарантии, что это сразу front поверхность Так же как и что это back поверхность.
-
> Игорь Шевченко © (24.03.08 14:25) [111] > oxffff © (24.03.08 13:34) [110] > > Ну все равно ведь нету :) у DC окна...
oxffff © (22.03.08 14:17) [21]
-
> [112] oxffff © (24.03.08 20:17)
читаем еще раз литературу, оконный DC не совместим с DC, который может рисовать на битмапах.
-
> Eraser © (24.03.08 20:24) [114]
Чего???????
-
> Eraser © (24.03.08 20:24) [114]
Вообще речь во всей ветке шла о количестве буферов перед тем попадет изображение на Front поверхность видеопамяти.
-
> Eraser © (24.03.08 20:24) [114] > > [112] oxffff © (24.03.08 20:17) > > читаем еще раз литературу, оконный DC не совместим с DC, > который может рисовать на битмапах.
Ты хочь понял что сказал, скажи почему есть битмап в оконном DC? И почему функции Bitblt в примерах выше работают?
-
> [116] oxffff © (24.03.08 20:28)
> Вообще речь во всей ветке шла о количестве буферов перед > тем попадет изображение на Front поверхность видеопамяти.
давай не будем касаться фронт-буфферов, драйверов и т.п., т.к. это совершенно другая тема, мало пересекающаяся с прикладным уровнем DC.
> скажи почему есть битмап в оконном DC?
не знаю почему он там есть.
> И почему функции Bitblt в примерах выше работают?
как они работают то? копируют ровно то, что есть в экранном контексте, легко доступном через CreateDC(PChar('DISPLAY'), nil, nil, nil); ни каких бэк-буфферов в этом битмапе или где либо еще на прикладном уровне я не наблюдал. если знаешь, где этот буффер - покажи, не знаешь - о чем тогда спор?
-
> давай не будем касаться фронт-буфферов, драйверов и т.п. > , т.к. это совершенно другая тема, мало пересекающаяся с > прикладным уровнем DC.
Речь шла как раз об этом.
> > скажи почему есть битмап в оконном DC? > > не знаю почему он там есть.
А чем ты рисуешь?
> > как они работают то? копируют ровно то, что есть в экранном > контексте, легко доступном через CreateDC(PChar('DISPLAY'), > nil, nil, nil); > ни каких бэк-буфферов в этом битмапе или где либо еще на > прикладном уровне я не наблюдал. > если знаешь, где этот буффер - покажи, не знаешь - о чем > тогда спор?
Разговор начался в самом самом начале о количестве буферов перед попаданием из MemDC в окно. То что буфер есть можно узнать по HBM := GetCurrentObject(DC, OBJ_BITMAP). А то что он необычный по провалу при вызове GetObject
-
> Разговор начался в самом самом начале о количестве буферов > перед попаданием из MemDC в окно.
Во front buf адаптера
-
> [119] oxffff © (24.03.08 20:54)
> А чем ты рисуешь?
я рисую контекстом устройства )) для того он и создан.
> А то что он необычный по провалу при вызове GetObject
ну используется для каких то системных нужд.. мало ли.
> Разговор начался в самом самом начале о количестве буферов > перед попаданием из MemDC в окно.
вот теперь понял.. каким образом оконный, пусть даже закрытый (private) контекст устройства может рисовать одновременно на битмапе и устройстве вывода изображения? ерунда какая-то получается. OWNDC создан просто для повышения быстродействия, кэширования никто и не обещал. каким образом достигается это повышение быстродействия - можно только косвенно догадываться. Системе нет смысла заниматься кэшированием битмапов и других растровых операций на прикладом уровне, для этого есть драйвер и вагон видеопамяти у видеокарты. На прикладном уровне и даже на верхнем ядерном уровне все происходит достаточно прозрачно.. все операции можно отследить с пом. того же зеркального видеодрайвера.
-
> Системе нет смысла заниматься кэшированием битмапов и других > растровых операций на прикладом уровне
уточню, GDI операции могут кэшироваться, для этого даже есть спец. функции, но в предыдущем посте речь о кэшировании уже отрисованой картинки, а не пакетном выполнении GDI операций.
-
> я рисую контекстом устройства )) для того он и создан.
Ты рисуешь как раз на этом битмапе. Действительно получается что битмап общий с clip областями. Фактически может представлять собой буфер в RAM или VIDEO памяти или являтся front буфером.
> OWNDC создан просто для повышения быстродействия, кэширования > никто и не обещал. каким образом достигается
Это понятно стало из примеров. :)
-
> Eraser © (24.03.08 21:14) [122]
Пойми что часть операций может выполнятся программно и аппратно в промежуточном буфере. <- о нем мы и начали разговор еще даже не этой теме.
-
> [123] oxffff © (24.03.08 21:19)
> Действительно получается что битмап общий с clip областями. > Фактически может представлять собой буфер в RAM или VIDEO > памяти или являтся front буфером.
там многое на усмотрение драйвера, скорее всего этот битмап просто не доступен из пользовательского режима.. у Юаня все структуры приведены и описано много, только у меня не текстовый вариант книги, по этому копи/паст не могу сделать. в любом случае мы можем принимать этот механизм только как данность, повлиять на его работу особо возможности нет, по крайней мере без внедрения и правки ВАП процесса или своего драйвера.
-
oxffff © (24.03.08 20:54) [119]
> То что буфер есть можно узнать по > HBM := GetCurrentObject(DC, OBJ_BITMAP).
Это не буфер нифига
> А то что он необычный по провалу при вызове GetObject
Вот потому и проваливается, что не буфер. Купи уже книжку Фэня Юаня и прочитай.
-
oxffff © (24.03.08 21:19) [123]
> Ты рисуешь как раз на этом битмапе.
Фига с два. Ты отдаешь команды рисования драйверу. А он уже определяет, где и как ему рисовать, то ли вызывать средства GDI (точнее, GRE - Graphics Rendering Engine - ядерная часть GDI), то ли вызывать аппаратные средства видеоадаптера.
Иначе получается, что аппаратные 3D ускорители занимаются анализом изображения нарисованного на битмапе, что есть ерунда.
Купи уже книжку Фэня Юаня.
-
А может, термин "двойной буфер" предполагает то, что 1-й буфер - это контекст окна, а второй - это контекст в памяти? А вовсе не то, какие битмапы присоединены к этим контекстам? :) Эдакая абстракция. Во втором "буфере" мы картинку отрисовали, а затем одним махом положили ее в первый, в контекст окна. А что там дольше будет происходить с этой картинкой, кто, куда и как будет что-то отправлять, кэшировать и буферизировать - это забота исключительно ОС. И спорить о глубинных процессах в ядре системы и драйверов прикладным программистам - это просто чесание языков, имхо )) Почему можно назвать контекст окна буфером - потому что мы ведь не сами отправляем данные в видеопамять или на обработку видеодрайверу. Мы ложим в одно общее место - в контекст, как во временное хранилище, откуда система уже по своим правилам и алгоритмам отправляет графику дальше, чтобы она попала в оконцовии на монитор. Куда система ложит, и как оттуда доставляет на экран монитора - не наша забота. Наша задача заканчивается на складывании данных в контекст.
-
> Игорь Шевченко © (25.03.08 09:43) [126] > oxffff © (24.03.08 20:54) [119] > > > > То что буфер есть можно узнать по > > HBM := GetCurrentObject(DC, OBJ_BITMAP). > > > Это не буфер нифига > > > > А то что он необычный по провалу при вызове GetObject > > > Вот потому и проваливается, что не буфер. Купи уже книжку > Фэня Юаня и прочитай.
Да что вы заладили Фэнь Юань,Фэнь Юань. Что своей головы нет чтоли?
>Это не буфер нифига.
Зачем он тогда нужен?
Это тот самый буфер на котором осуществляется вывод. В зависимости от использования способа отрисовки вы он расположен в ведении драйвера, либо в ведении Windows.
-
> Игорь Шевченко © (25.03.08 09:46) [127] > oxffff © (24.03.08 21:19) [123] > > > > Ты рисуешь как раз на этом битмапе. > > > Фига с два. Ты отдаешь команды рисования драйверу. А он > уже определяет, где и как ему рисовать, то ли вызывать средства > GDI (точнее, GRE - Graphics Rendering Engine - ядерная часть > GDI), то ли вызывать аппаратные средства видеоадаптера. >
> > Купи уже книжку Фэня Юаня.
Что своей головы нет чтоли?
> Фига с два. Ты отдаешь команды рисования драйверу. А он > уже определяет, где и как ему рисовать, то ли вызывать средства > GDI (точнее, GRE - Graphics Rendering Engine - ядерная часть > GDI), то ли вызывать аппаратные средства видеоадаптера.
Судя по вашим слова в каждом драйвере видеоадаптера есть идентичный код который вызывает ядерные функции GDI в случая отсутствия функциональности.
Вопрос не кажется ли вам это не разумным? А может более логично GDI опрашивает драйвер на предмет поддержки функциональности аля GetDeviceCaps и в случае неподдержки осуществляет вывод самостоятельно на поверхности (буфере, битмапе, назовите как угодно, но вывод должен на чем то осуществляться) А в случае аппартаной поддержки window DC битмап является просто оберткой над аппаратным буффером.
> Иначе получается, что аппаратные 3D ускорители занимаются > анализом изображения нарисованного на битмапе, что есть > ерунда.
Откуда такой вывод? Вы рисуете на битмапе в зависимости от расположения он либо в RAM, либо на поверхности front или back VIDEORAM.
-
>Купи уже книжку Фэня Юаня.
Что говорит Фэня Юань о назначении Bitmap Window DC?
-
oxffff © (25.03.08 13:08) [129]
> Это тот самый буфер на котором осуществляется вывод.
Доказательства будут ?
> Что своей головы нет чтоли?
Есть.
> Зачем он тогда нужен?
а. Почему ты считаешь, что это буфер ? б. Затем, чтобы GDI не ломался
-
> Вы рисуете на битмапе в зависимости от расположения он либо > в RAM, либо на поверхности front или back VIDEORAM.
Нет. Я не рисую на битмапе. На битмапе рисует драйвер, GRE, либо процессор видеоадаптера, которому подаются специальные команды.
Купи уже книжку Фэня Юаня и почитай.
-
> б. Затем, чтобы GDI не ломался
А с чего ему ломаться?
Этот битмап window DC является Clip частью общего Display DC. И расположен он либо в RAM, либо VRAM.
-
> Игорь Шевченко © (25.03.08 13:28) [133] > > > Вы рисуете на битмапе в зависимости от расположения он > либо > > в RAM, либо на поверхности front или back VIDEORAM. > > > Нет. Я не рисую на битмапе. На битмапе рисует драйвер, GRE, > либо процессор видеоадаптера, которому подаются специальные > команды. > > Купи уже книжку Фэня Юаня и почитай.
А чем разница? Смысл один и тот же.
-
oxffff © (25.03.08 13:29) [134]
> Этот битмап window DC является Clip частью общего Display > DC. > И расположен он либо в RAM, либо VRAM.
Доказательства будут ?
-
> > Доказательства будут ?
А вы подумайте зачем нужна эта поверхность.
А еще лучше подумайте на тем, что нельзя заменить через SelectObject Bitmaps device context. И я наконец думаю вам все станет понятно.
А в memoryDC кто рисует? Программа или апаратно? И зачем там нужен битмап? Не догадываетесь?
-
Да и прочитайте наконец CreateCompatibleDC
Before an application can use a memory device context for drawing operations, it must select a bitmap of the correct width and height into the device context. This may be done by using CreateCompatibleBitmap to specify the height, width, and color organization required in the function call.
-
oxffff © (25.03.08 13:34) [137]
Я вроде задал конкретный вопрос - доказательства твоему утверждению, что тот битмап, который ты вынимаешь из оконного DC через GetCurrentObject, есть буфер, на котором рисуется изображение, будут ?
-
oxffff © (25.03.08 13:38) [138]
> Before an application can use a memory device context for > drawing operations, it must select a bitmap of the correct > width and height into the device context.
Я тебе открою секрет - при создании MemoryDeviceContext в нем по умолчанию создается монохромный битмап размер 1 х 1 пиксель, на котором рисовать неудобно. Поэтому туда необходимо выбрать битмап с correct width и height.
Купи уже книжку Фэня Юаня и прочитай.
-
> oxffff
да дался тебе этот фронт буфер :)) доколупался до него как пьяный до радио :)
-
> Я тебе открою секрет - при создании MemoryDeviceContext > в нем по умолчанию создается монохромный битмап размер 1 > х 1 пиксель, на котором рисовать неудобно.
Секрет? :)
То есть вы уже признаете, что это буфер на котором вы рисуете (GDI, adapter).
-
> Игорь Шевченко © (25.03.08 13:49) [139] > oxffff © (25.03.08 13:34) [137] > > Я вроде задал конкретный вопрос - доказательства твоему > утверждению, что тот битмап, который ты вынимаешь из оконного > DC через GetCurrentObject, есть буфер, на котором рисуется > изображение, будут ?
Отвечу вопросом на вопрос. Зачем Bitmap в DC?. Почему SelectObject именно так рабатает? Вас это не наводит на мысли? И почему handle из GetCurrentObject не может быть оберткой VIDEO или RAM поверхности?
P.S. Что Фэнь Юань говорит по этому поводу? Что уже молчит или вы его сами не дочитали? :)
-
oxffff © (26.03.08 07:47) [142] > Секрет? :) > > То есть вы уже признаете, что это буфер на котором вы рисуете > (GDI, adapter).
ключевое слово в моем посте MemoryDeviceContext oxffff © (26.03.08 07:53) [143] > Отвечу вопросом на вопрос. Зачем Bitmap в DC?. > Почему SelectObject именно так рабатает? > Вас это не наводит на мысли? > И почему handle из GetCurrentObject не может быть оберткой > VIDEO или RAM поверхности?
Что нам пишут разработчики Wine: "Eurdora 4.x and 5.x crash when handling a WM_PAINT message. The program gets a hdc from BeginPaint() and does a GetCurrentObject(hdc,OBJ_BITMAP) on that device context. In wine zero is returned and the program crashes as a result of that (step tracing it shows some math on it and then uses the result as a pointer). The same problem was reported on the developer list in: http://www.winehq.com/hypermail/wine-devel/2002/11/0599.htmSince the program does not do anything suspicious between aquiring the dc handle and the GetCurrentObject, Checking under Windows (Win2000). I found that GetCurrentObject(,OBJ_BITMAP) on the the dc returned both by BeginPaint() and CreateDC(), retrieves a non-zero handle. The handle looks genuine, but the bitmap does not appear to be valid (funny dimensions and so). My proposed solution is to do what CreatCompatibleDC already does: load a default bitmap in CreateDC(). This has worked here for a long time without any aparent problems." http://www.winehq.org/pipermail/wine-patches/2003-January/005138.htmlТо есть, они предполагают, что для совместимости с кривыми программами в Windows GDI в DC встроен некий фиктивный объект, дабы программы не ломались. Что вполне соответствует идеологии Windows, вспомнить хотя бы хак для SimCity. Ты можешь написать программу, которая будет выбирать этот bitmap для разных окон и пытаться узнать его характеристики через GetObject. Для окон класса tooltip_class32 этот битмап вполне валидный и имеет некие корректные размеры.
-
> То есть, они предполагают, что для совместимости с кривыми > программами в Windows GDI в DC встроен некий фиктивный объект, > дабы программы не ломались.
вот оно истинное человеколюбие =) а под линухами - все честно по-пионерски рушится к едрене фене =)
-
> > То есть, они предполагают, что для совместимости с кривыми > программами в Windows GDI в DC встроен некий фиктивный объект, > дабы программы не ломались. Что вполне соответствует идеологии > Windows, вспомнить хотя бы хак для SimCity.
Честно говоря я прочитал текст и не нашел места где они что-то предполагают. :) Перечитал еще раз и не нашел.
А судя по
>The handle looks genuine, but the bitmap does not appear to be valid (funny >dimensions and so).
у меня возникают подозрения, что проверять результат функции их не научили. :)
>дабы программы не ломались.
Я по этому поводу думаю, что это некая поверхность. И скорее всего она расположена в большинстве случаев сегодня в видеопамяти по скольку современные видеокарты поддерживают аппаратно большинство атомарных графических операций. Если это поверхность является front поверхностью, то мы наблюдает фактически DIRECTDRAW. Однако в более раннем возрасте эта поверхность могла кочевать из RAM в VRAM в зависимости от поддержки операций. А как известно это дорогая операция. Особенно при обработке WM_PAINT Думаю было сознательно принято решение ограничить взаимодействие с этой поверхностью для функций SelectObject дабы во первых сократить издержки при передачи из VRAM в RAM. а во вторых формат аппаратной поверхности мог отличать от DIB формата, что приводило бы к задержкам при преобразовании при вызове selectObject device format <-> DIB формат <-> device format. А GetObject не мог корретно возвращать информацию об аппаратной поверхности. Поэтому это дело просто запретили. А Handle оставили поскольку устройство поддерживает RC_BITBLT (Capable of transferring bitmaps).
Это IMHO.
А поскольку аппаратная
расположена
-
oxffff © (26.03.08 20:47) [146]
> Я по этому поводу думаю, что это некая поверхность. И скорее > всего она расположена в большинстве случаев сегодня в видеопамяти > по скольку > современные видеокарты поддерживают аппаратно большинство > атомарных графических операций. Если это поверхность является > front поверхностью, то мы наблюдает фактически DIRECTDRAW. >
А ты не думай. Ты найди подтверждение своим словам. Я вот искал - не нашел.
> Это IMHO.
Ты тогда подумай, как видеокарты текст выводят. Или тоже рисунок на поверхности анализируют ?
-
> Или тоже рисунок на поверхности анализируют ?
А зачем проводить анализ?
-
TEXTCAPS Value that indicates the text capabilities of the device, as shown in the following list: TC_CP_STROKE Device is capable of stroke clip precision. TC_CR_90 Device is capable of 90-degree character rotation. TC_CR_ANY Device is capable of any character rotation. TC_EA_DOUBLE Device can draw double-weight characters. TC_IA_ABLE Device can italicize. TC_OP_CHARACTER Device is capable of character output precision. TC_OP_STROKE Device is capable of stroke output precision. TC_RA_ABLE Device can draw raster fonts. TC_RESERVED Reserved; must be zero. TC_SA_CONTIN Device uses any multiples for exact character scaling. TC_SA_DOUBLE Device is capable of doubled character for scaling. TC_SA_INTEGER Device uses integer multiples only for character scaling. TC_SCROLLBLT Device cannot scroll using a bit-block transfer. This meaning may be the opposite of what you expect. TC_SF_X_YINDEP Device can scale independently in the x- and y-directions. TC_SO_ABLE Device can draw strikeouts. TC_UA_ABLE Device can underline. TC_VA_ABLE Device can draw vector fonts.
-
> Или тоже рисунок на поверхности анализируют ?
Даже если это аппаратно не поддерживается, ничего не мешает делать это программно. Или преобразовывать в набор примитивных операций. Зачем проводить анализ?
-
oxffff © (26.03.08 20:53) [148]
> А зачем проводить анализ?
Ну если функции GDI рисуют на битмапе, а видеоадаптер сам умеет текст выводить ? Текст, он тоже функциями GDI рисуется. Очевидно, адаптеру придется битмап с рисунком текста анализировать.
Я уже вполне серьезно - почитай Фэня Юаня. Он хорошую книжку написал.
oxffff © (26.03.08 20:55) [149]
Вот этот пост к чему ?
И еще: У некоторых окон битмап, получаемый по GetCurrentObject из DC их окна вполне себе валидный. С размерами, возвращаемыми по GetObject.
А у всех остальных он невалидный, и HBITMAP имеет одно и то же значение. Совсем как Stock Object.
-
oxffff © (26.03.08 21:02) [150]
Давай ты уже подтвердишь свою версию ? Примерами, ссылками, дизассемблированием GDI32.DLL и WIN32K.SYS
-
> Ну если функции GDI рисуют на битмапе, а видеоадаптер сам > умеет текст выводить ? Текст, он тоже функциями GDI рисуется. > Очевидно, адаптеру придется битмап с рисунком текста анализировать. >
Вы внимательно [146] читали? Зачем адаптеру проводить анализ? Он не знает что такое текст. Однако хорошо знает растровую поверхность. Текст программно отрисовался. И поверхность передалась адаптеру. А в случае аппартной отрисовки поверхности (bitmap) расположен в памяти адаптера. Зачем проводить анализ?
-
> Я уже вполне серьезно - почитай Фэня Юаня. Он хорошую книжку > написал.
Почему Фэнь Юань не затрагивает данный вопрос. Вы внимательно то сами читали его? :)
-
> Игорь Шевченко © (26.03.08 21:06) [152] > oxffff © (26.03.08 21:02) [150] > > Давай ты уже подтвердишь свою версию ? Примерами, ссылками, > дизассемблированием GDI32.DLL и WIN32K.SYS
Зачем лезть за int 2e? Может не стоит из пушки по воробьям?
-
oxffff © (26.03.08 21:23) [153]
> Зачем адаптеру проводить анализ? Он не знает что такое текст.
В том-то и дело, что знает.
> TC_CR_90 Device is capable of 90-degree character rotation. > > TC_CR_ANY Device is capable of any character rotation. > > TC_EA_DOUBLE Device can draw double-weight characters. > > TC_IA_ABLE Device can italicize. > TC_OP_CHARACTER Device is capable of character output precision. > > TC_OP_STROKE Device is capable of stroke output precision. >
Слово "Device" тебе тут ничего не говорит ?
> Вы внимательно [146] читали?
Да я-то внимательно читал. Только я сильно сомневаюсь в верности изложенного в [146]
> Зачем лезть за int 2e? > Может не стоит из пушки по воробьям?
GDI32 вообще-то библиотека пользовательского режима, и ряд функций выполняет без обращения к ядру. И часть DC тоже находится в памяти, доступной из пользовательского режима.
Впрочем ладно. Я жду доказательств или опровержений [146].
-
> В том-то и дело, что знает.
Вы не ответили на вопрос. Зачем проводить анализ изображение в случае программной отрисовки?
>Слово "Device" тебе тут ничего не говорит ?
Так это оно вам должно говорить, я для этого вам их привел.
> Да я-то внимательно читал. Только я сильно сомневаюсь в > верности изложенного в [146]
Так вы предложите что то свое. Или хотя бы скажите что говорит Фень Юань. Или он как вы тоже молчит.
>GDI32 вообще-то библиотека пользовательского режима, и ряд функций >выполняет без обращения к ядру. И часть DC тоже находится в памяти, >доступной из пользовательского режима.
Вообще то нужная функциональность лезет в ntdll.exe и win32k.sys, то есть через шлюз вызова Int 2e.
-
> ntdll.exe
ntoskrnl.exe
-
> Вы внимательно [146] читали?
Я вот тоже почитал, пока впечатление такое, что ты слишком много думаешь. :) Помниться, я тоже думал, что самый умный, поэтому могу своими размышлениями сам до всего дойти, не обращаясь к другим источникам информации. Вот у меня такое же впечатление - много размышлений, вопросов к собеседнику в духе "а вот ты сам подумай, зачем то-то и то-то" и мало конкретных ответов и конкретных фактов. Складывается впечатление, что по большей части выдуманно на основании обрывочных свединей.
-
> не обращаясь к другим источникам информации.
Честно говоря хваленный неоднократно тут Фэнь Юань вообще избегает данной темы, так что куда мне уж тут. А судьи кто?
-
> Игорь Шевченко © (26.03.08 21:33) [156]
Вот то что поддерживает устройство по тексту.
procedure TForm1.Button1Click(Sender: TObject); const CONST_TECHNOLOGY:array[DT_PLOTTER..DT_DISPFILE] of string=('DT_PLOTTER','DT_RASDISPLAY','DT_RASPRINTER','DT_RASCAMERA','DT_CHARSTRE AM','DT_METAFILE','DT_DISPFILE'); CONST_TEXTCAPS:array[0..16] of string=( 'TC_OP_CHARACTER','TC_OP_STROKE','TC_CP_STROKE','TC_CR_90', 'TC_CR_ANY','TC_SF_X_YINDEP','TC_SA_DOUBLE','TC_SA_INTEGER', 'TC_SA_CONTIN','TC_EA_DOUBLE','TC_IA_ABLE', 'TC_UA_ABLE','TC_SO_ABLE','TC_RA_ABLE','TC_VA_ABLE', 'TC_RESERVED','TC_SCROLLBLT'); var dc:Thandle; ATEXTCAPS:DWORD; i:integer;
procedure GetTextCap(IDX:DWORD); begin if LONGBOOL((ATEXTCAPS AND (1 shl IDX))) then Memo1.Lines.add(CONST_TEXTCAPS[IDX]); end;
begin dc:=GetDC(handle); Memo1.lines.add(CONST_TECHNOLOGY[GetDeviceCaps(dc,TECHNOLOGY)]); Memo1.lines.add('NUMFONTS '+Inttostr(GetDeviceCaps(dc,NUMFONTS))); ATEXTCAPS:=GetDeviceCaps(dc,TEXTCAPS); for i:=0 to length(CONST_TEXTCAPS)-1 do GetTextCap(i); end;
-
ReleaseDC естественно.
-
> Вы не ответили на вопрос. Зачем проводить анализ изображение > в случае программной отрисовки?
Еще раз - адаптер умеет выводить текст сам. Драйвер адаптера об этом осведомлен. Ты же утверждаешь, что весь вывод производится на bitmap, который ты выбрал по GetCurrentObject из DC, а потом этот битмап пересылается в адаптер. Как в этом случае используются возможности адаптера по выводу текста ?
-
> oxffff © (26.03.08 22:10) [160]
Тыкаю носом в Феня Юаня стр. 119. Он пишет то же самое о чем я говорю.
Создается впечатление, что кто плохо не внимательно читал. А кто вообще не читал и ему не мешает.
-
oxffff © (26.03.08 22:13) [161]
Уважаемый, а где собственно доказательства твоих умозаключений из [146] ?
Не стоит сбиваться на второстепенные вопросы, давай ты уже потдвердишь то, что утверждаешь, а именно, что битмап, который выбирается по GetCurrentObject из оконного DC является или буфером, или окном в видеопамять, или чем-либо еще, на чем рисуется и что потом отдается видеоадаптеру.
-
> Еще раз - адаптер умеет выводить текст сам. Драйвер адаптера > об этом осведомлен. Ты же утверждаешь, что весь вывод производится > на bitmap, который ты выбрал по GetCurrentObject из DC, > а потом этот битмап пересылается в адаптер. Как в этом случае > используются возможности адаптера по выводу текста ?
Я вам 10 раз повторяю, что поверхность может быть создана адаптером в его памяти, исходная поверхность из RAM копируется в VRAM. Происходит аппаратная операция. И итоговая поверхность возвращается или не возращается в RAM. Мы же с вами это уже обсудили постов 60 назад.
-
> Игорь Шевченко © (26.03.08 22:27) [165]
Перечитайте заново Юаня, судя по всему вы пропустили некоторые моменты. Стр.119-122. И я тоже обязательно его прочитаю, во всяком случае добавлю в копилку еще знаний. За Юаня спасибо, прикуплю обязательно.
-
oxffff © (26.03.08 22:25) [164]
> стр. 119. Он пишет то же самое о чем я говорю.
А процитировать не затруднит ? А то у меня книжки сейчас под рукой нету, в страницу не могу посмотреть.
> Тыкаю носом
И повежливее, дружок, повежливее
-
> Я вам 10 раз повторяю, что поверхность может быть создана > адаптером в его памяти
Доказательства в студию
-
> И повежливее, дружок, повежливее
Это не вам лично. :)
Уж не обижайтесь. А то Юань Юань, сказали бы где прочитать. И тема закрыта была. Звиняйте. :)
У меня скан из инета. И то стр. 119 и 122. 120 и 121 нет.
Сейчас полную версию пытаюсь найти
-
> Игорь Шевченко © (26.03.08 22:32) [169] > > > Я вам 10 раз повторяю, что поверхность может быть создана > > > адаптером в его памяти > > > Доказательства в студию
DrvCopyBits EngCreateDeviceSurface
-
> EngCreateDeviceSurface
Это я в курсе вообще-то. Это вообще-то функция Win32k.sys, которая вызывает соответствующую функцию драйвера, и которая поверхность к битмапу в DC никоим боком не относится.
-
> Игорь Шевченко © (26.03.08 22:46) [172]
Интересно а про бит гранулярности вы тоже знаете и про IRQL? :) Так что предлагаю без лишних "это я тоже знаю". А зачем спрашиваете?. Ну да ладно теперь к делу.
Итак мы с вами в предыдущих постах сошлись во мнении, что существует некая общая поверхность, окном в которую является window DC битмап. Также мы выяснили (стр.119-122, 120-121стр. у меня нет), что в процессе драйвер може создавать свои поверхности, а также поверхности могут быть созданы в RAM памяти управляемые GRE. Так же там написано, что результат программных и аппаратных операций смешивается. Таким образом можно сделать вывод, что window DC битмап является окном на одну из таких поверхностей (а именно итоговую). Но процессе ее получения могут быть созданы несколько GRE и device managed поверхностей. Теперь вопрос, вас еще что-то не устраивает?
-
oxffff © (26.03.08 22:59) [173]
> Итак мы с вами в предыдущих постах сошлись во мнении, что > существует некая общая поверхность, окном в которую является > window DC битмап.
Нет, не сошлись. Именно это я и прошу доказать.
Я имею мнение, что существует поверхность растра, для устройства, на которой в итоге и производится рисование, как методами GRE (ядерная часть GDI)m так и методами адаптера, которые методы вызываются общими фукциями для ядерной части GDI.
> Также мы выяснили (стр.119-122, 120-121стр. у меня нет), > что в процессе драйвер може создавать свои поверхности, > а также поверхности могут быть созданы в RAM памяти управляемые > GRE.
В этом сходимся, все верно.
> Таким образом можно сделать вывод, что window DC битмап > является окном на одну из таких поверхностей (а именно итоговую). > Но процессе ее получения могут быть созданы несколько GRE > и device managed поверхностей
Нельзя сделать вывод. Я специально смотрел на битмап у DC разынх окон. Еще раз повторю, что у окон класса, например, tooltip_class32 это вполне валидный битмап, с размерами.
Со стилем класса CS_SAVEBITS он не соотносится.
-
Мдя... А кто-то еще в немастерстве весь форум за исключение Сергея М. упрекал... От оно как оказывается...
-
> Rouse_ © (26.03.08 23:09) [175]
Ну тебя лично я уже на немастерстве подлавливал. Ты насколько помню передачей параметра и работой c EAX напортачил. Да и где твои работы по расширению возможностей языка?
-
> А судьи кто?
Никаких судей, совершенно верно. Никаких претензий. Самому просто интересно было бы об этом узнать, но в этой ветке пока очень мало конкретных фактов. Правда, со стороны Игоря мнение ощущается гораздо более подтвержденным (ничего личного).
-
Fantasist... (26.03.08 23:16) [177]
Очевидно мне надо зарегистрироваться под другим ником
-
> Нет, не сошлись. Именно это я и прошу доказать. > > Я имею мнение, что существует поверхность растра, для устройства, > на которой в итоге и производится рисование, как методами > GRE (ядерная часть GDI)m так и методами адаптера, которые > методы вызываются общими фукциями для ядерной части GDI. >
Давайте определять местоположение итогового растра. Это поверхности видеопамяти. А поскольку device формат может не является DIB форматом, то и получить его описание через вызов упомянутой функции приводит к промаху.
> Нельзя сделать вывод. Я специально смотрел на битмап у DC > разынх окон. Еще раз повторю, что у окон класса, например, > tooltip_class32 это вполне валидный битмап, с размерами. >
Для небольших областей, не имеет смысл вызывать аппаратные функци, если вызов сравним по затратам с программной отрисовкой. И не будет penalty для перекачки VRAM<->RAM преобразования формата в DIB и обратно. Поэтому такая поверхность может быть кеширована в GRE поверхности которая DIB и соотвественно вызов Getobject успешный. А возможно используется поверхность последней операции. которая может быть пребуфером в RAM или VRAM(но не являться front поверхностью).
Доказать это можно только посидев в отладчике ядра и отследив весь IRP стек. У вас есть время? У меня его нет.
-
> А возможно используется поверхность последней операции. > которая может быть пребуфером в RAM или VRAM(но не являться > front поверхностью).
И поэтому в зависимости от ее положения она либо DIB либо DEVICE формата. Соответствующим образом ведет себя и Getobject. Я именно к этому склоняюсь.
-
> Я имею мнение, что существует поверхность растра, для устройства, > на которой в итоге и производится рисование, как методами > GRE (ядерная часть GDI)m так и методами адаптера, которые > методы вызываются общими фукциями для ядерной части GDI. >
Я все таки думаю нужно различать местоположение поверхности.
Вы согласны с тем, что если поверхность device - то рисует устройство, но не x86 код?
А если GRE поверхность значит она в RAM - и рисовать может как x86 код (программный отрисовщик), либо использовать отражение видеопамяти на RAM память, что честно говоря менее эффективно чем использование VRAM.
-
oxffff © (26.03.08 23:30) [179]
Давайте пойдем не от логики - мы все таки не на философском диспуте, Windows вполне конкретная программа, работает по вполне конкретным алгоритмам, их можно проверить. Вот от этого и пойдем.
> А поскольку device формат может не является DIB форматом, > то и получить его описание через вызов упомянутой функции > приводит к промаху.
А что, в DC может сидеть объект, который нельзя опросить функцией GetObject ? Наверное его можно опросить другой функцией ?
-
> А что, в DC может сидеть объект, который нельзя опросить > функцией GetObject ?
Так я ваш пример поправил как раз на провале GetObject.
>Наверное его можно опросить другой функцией ?
Знаете скажите.
-
> Вы согласны с тем, что если поверхность device - то рисует > устройство, но не x86 код?
Нет, не согласен. Это всего лишь формат растра. На растрах DDB может рисовать GDI, что он вполне успешно и делает.
-
> Игорь Шевченко © (26.03.08 23:48) [182]
GetObject(a,sizeof(b),@b); Дальше sysenter я естественно не добрался.
-
> Игорь Шевченко © (26.03.08 23:55) [184]
Скажите а где расположены device поверхности(в какой памяти)? И как туда (VRAM) доберется x86 код?
-
> Наверное его можно опросить другой функцией ?
HGDIOBJ
The 24th bit position says whether it is a stock object or not. Как раз GetObject и валится на одном из таких.
-
-
> HGDIOBJ > > The 24th bit position says whether it is a stock object > or not.
ADC := GetDC(Wnd); try HBM := GetCurrentObject (ADC, OBJ_BITMAP); ShowMessageFmt('%.8x', [Integer(HBM)]);
Показывает 01050050. 24-й бит установлен в единицу (01)
-
> ли ты помнишь, разговор начался с того, имеет ли оконный > DC буфер. Я сильно надеюсь, что мы уже убедились в том, > что не имеет ?
С вами разговор начался с этого. С этим я согласен, в том смысле что нет у него персонального буфера, но есть общий и не один при отрисовке.
-
01050050 shr 16
gdi_objtypeb_bitmap = 0x05,
-
> Что есть "device поверхности" ?
В моем понимании, это поверхность device формата расположенная в видеопамяти или отображенной RAM памяти, доступная видеоадаптеру и над которой он(видеоадаптер) выполняет аппаратные операции.
GRE поверхность поверхность RAM памяти, над которой выполняются операции программно, либо аппаратно в случае отображения (однако это менее эффективно чем аппаратные операции в видеопамяти)
-
oxffff © (27.03.08 00:31) [191]
> 01050050 shr 16 > > gdi_objtypeb_bitmap = 0x05,
Да, потому что GetCurrentObject(ADC, OBJ_BITMAP)
осталось сделать shr 24 и убедиться, что бит stock object установлен.
-
> Игорь Шевченко © (27.03.08 00:23) [189]
Наша задача установить причину поведения Getobject. Я свое мнение озвучил. А где ваше? :)
P.S. Пошел спать. Завтра(сегодня) я очень надеюсь продолжим изыскания. Может и Юаня успею прочитать, относящееся к теме.
-
> Да, потому что GetCurrentObject(ADC, OBJ_BITMAP)
Вообще то OBJ_BITMAP=7.
-
oxffff © (27.03.08 00:41) [195]
> Вообще то OBJ_BITMAP=7.
Это несвязанные константы. Типы handle GDI и типы выбираемых объектов. Опять же, Фэнь Юань. Я кстати ссылку на книжку дал.
-
> Это несвязанные константы. Типы handle GDI и типы выбираемых > объектов. > Опять же, Фэнь Юань. Я кстати ссылку на книжку дал.
Юань, Юань. Google HGDIOBJ structure. :)
Но вопрос о Getobject остается и о типе поверхности остается. Кстати а у tooltip_class32 какой интересно тип для которого Getobject отрабатывает.
P.S. Все теперь точно спать.
-
> Кстати а у tooltip_class32 какой интересно тип для которого > Getobject отрабатывает.
HBITMAP
-
> Игорь Шевченко © (27.03.08 12:59) [198]
:).
Вид handle побитово.
-
> Вид handle побитово.
BC05126E Вот, собственно, программка:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure RefreshWindowList;
end;
var
Form1: TForm1;
implementation
uses
HSHookUtils;
procedure TForm1.Button1Click(Sender: TObject);
begin
RefreshWindowList;
end;
function EnumWindowProc (Wnd: HWND; Param: LPARAM): Integer; stdcall;
var
AClassName: array[0..255] of char;
AStyle: DWORD;
begin
GetClassName(Wnd, AClassName, SizeOf(AClassName));
AStyle := GetClassLong(Wnd, GCL_STYLE);
with TForm1(Param) do
ListBox1.Items.AddObject(Format('%s (%.8x)', [AClassName, AStyle]),
TObject(Wnd));
Result := 1;
end;
procedure TForm1.Button2Click(Sender: TObject);
const
GOStatus: array[Boolean] of string = ('Failed', 'Success');
var
Wnd: HWND;
ADC: HDC;
Bmp: HBITMAP;
Info: TagBITMAP;
Success: Boolean;
BmInfoStr: string;
begin
if ListBox1.ItemIndex <> -1 then
begin
Wnd := HWND(ListBox1.Items.Objects[ListBox1.ItemIndex]);
if IsWindow(Wnd) then
begin
ADC := GetWindowDC(Wnd);
try
Bmp := GetCurrentObject(ADC, OBJ_BITMAP);
Success := GetObject(Bmp, SizeOf(Info), @Info) <> 0;
if Success then
BmInfoStr := Format('%d (%d x %d)', [Info.bmType, Info.bmWidth,
Info.bmHeight])
else
BmInfoStr := 'No info';
ShowMessageFmt('%.8x = %s (%s) %s', [Integer(Bmp), DecodeGDIHandle(Bmp),
GOStatus[Success], BMInfoStr]);
finally
ReleaseDC(Wnd, ADC);
end;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RefreshWindowList;
end;
procedure TForm1.RefreshWindowList;
begin
ListBox1.Clear;
EnumWindows(@EnumWindowProc, LPARAM(Self));
end;
end. unit HSHookUtils;
interface
function DecodeGDIHandle (const AHandle: Cardinal): string;
implementation
uses
SysUtils;
function DecodeGDIHandle (const AHandle : Cardinal) : String;
var
StockObject : Boolean;
ObjectType,
Index : Integer;
ObjectTypeName : String;
begin
if (AHandle = 0) then begin
Result := 'NULL';
Exit;
end;
StockObject := (AHandle AND $800000) <> 0;
ObjectType := (AHandle SHR 16) AND $7F;
Index := LOWORD(AHandle);
case ObjectType of
1:
ObjectTypeName := 'HDC';
4:
ObjectTypeName := 'HRGN';
5:
ObjectTypeName := 'HBITMAP';
8:
ObjectTypeName := 'HPALETTE';
$0A:
ObjectTypeName := 'HFONT';
$10:
ObjectTypeName := 'HBRUSH';
$21:
ObjectTypeName := 'HENHMETAFILE';
$30:
ObjectTypeName := 'HPEN';
$50:
ObjectTypeName := 'HEXTPEN';
else
ObjectTypeName := '*ERROR*'+Format('%.2x', [ObjectType]);
end;
if StockObject then
ObjectTypeName := 'S_'+ObjectTypeName;
Result := Format('%s(%.4x)', [ObjectTypeName, Index]);
end;
end. Можешь сам попробовать
-
кстати, в программке неверно StockObject судя по всему определяется, но это не страшно
-
> Можешь сам попробовать
Спасибо конечно. Но я как то и сходу могу установить вид глядя на BC05126E. :)
вот бы удалось расшифровать ВС. Ну нулевой понятно Stock. А вот остальное. У вас случаем нет информации о битах 25-31?
-
> oxffff © (27.03.08 22:19) [202]
В данном случае BC - это не stock object. Так что то же значит BC. :)
-
"Манипулятор объекта GDI начинается с 8 старших бит, смысл которых пока неизвестен; далее следуют: 1 бит признака стандартного объекта, 7 бит с информацией о типе объекта и 16-битного индекса, старшие 4 бита которого всегда равны 0." (с) Фень Юань, стр. 155
Судя по значениям HGDIOBJ от GetStockObject, с позицией бита стандартного объекта что-то изменилось по сравению с Windows 2000 - я работаю на XP, и там HGDIOBJ такие:
GetStockObject(0) - 01900010 GetStockObject(1) - 01900014 GetStockObject(2) - 01900012 GetStockObject(3) - 01900013 GetStockObject(4) - 01900011 GetStockObject(5) - 01900015 GetStockObject(6) - 01B00018 GetStockObject(7) - 01B00017 GetStockObject(8) - 01B00016 GetStockObject(9) - 00000000 GetStockObject(10) - 018A0023 GetStockObject(11) - 018A0028 GetStockObject(12) - 018A0027 GetStockObject(13) - 018A0021 GetStockObject(14) - 018A0026 GetStockObject(15) - 0188000B GetStockObject(16) - 018A0025 GetStockObject(17) - 018A0029 GetStockObject(18) - 0290001C GetStockObject(19) - 01B00019 GetStockObject(20) - 0189001F GetStockObject(21) - 0185000F - тот самый Bitmap (1x1) который выбран по умолчанию в MemoryDeviceContext
-
"При анализе структуры манипуляторов GDI в разделе «Поиск таблицы объек- тов GDI» нерасшифрованными остались лишь старшие 8 бит. Дополнительные эксперименты показывают, что в них хранится счетчик повторного использования — еще одно простое средство проверки манипуляторов. У каждого элемента таблицы объектов GDI первоначальное значение счетчика равно 0. Когда в элемент таблицы заносится информация о новом объекте GDI, его счетчик повторного использования увеличивается (когда значение достигает 255, счетчик снова сбрасывается в 0). Таким образом, когда элемент задействуется впервые, его счетчик повторного использования равен 0x01; это относится ко всем стандартным объектам GDI, которые создаются один раз и никогда не удаляются. Если вы удаляете объект GDI и создаете новый объект в том же элементе таблицы, даже при совпадении типов объектов манипуляторы будут отличаться, поскольку значение счетчика повторного использования увеличилось. Все вызовы функций, в которых присутствует исходный манипулятор, завершатся неудачей." (с) оттуда же, стр 169.
К вопросу о том, что такое BC
|