Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Свитки
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  16:36[Войти] | [Зарегистрироваться]

Обсуждение материала
Основы работы с Win API в VCL-приложениях
Полный текст материала


Другие публикации автора: Антон Григорьев

Цитата или краткий комментарий:

«... В данной статье будет говориться о том, как совместить использование Win API (Application Programming Interface) и компоненты VCL. Статья ориентирована на человека, который уже умеет писать приложения с помощью VCL Delphi и хочет научиться расширять их функциональность с помощью API. ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]24100%
 
  Ничего особенно нового и интересного
[2]00%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 24

Оценка стиля изложения

  Все понятно, материал читается легко
[1]1768%
 
  Есть неясности в изложении
[2]624%
 
  Непонятно написано, трудно читается
[3]28%
 
Всего проголосовали: 25




Смотрите также материалы по темам:
[Ядро, структуры и механизмы Windows, использование API]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 56

15-10-2010 04:10
Ronald McDonald, опучатка жЕ!

Статья отличная!
 exo


23-04-2009 08:43
В книге BS_PUSBUTTON.

В статье же все как ни странно верно. Кому верить?)

CreateWindow('BUTTON', 'Test', WS_Visible or BS_PushButton or WS_Popup, 10, 10, 100, 50, 0, 0, HInstance, nil);



08-03-2009 03:29
Кеш гугла еще никто не отменил: http://209.85.229.132/search?q=cache:IBfKM8IOsrwJ:janych.selfip.com/Examples/Delphi/MemoryLeak/+UdebugMemoryLeak.pas+site:janych.selfip.com&hl=uk&ct=clnk&cd=1&gl=ua&client=firefox-a


07-03-2009 22:42
сообщение от автора материала
Думается, что приложение сразу берёт большой кусок памяти у системы, а потом в этом большом куске резервируются участки через new/getMem/realloc.

Да, это действительно так. Но это не отменяет того, что я сказал - что память не сразу возвращается системе.

Там есть ещё вроде как различия в зависимости от размеров создаваемых переменных. Для "мелких" используется участок памяти, который системе вообще не возвращается, пока программа не завершится. Хотя я уже не помню, давно разбирался, и только с "семёркой".

Как раз в семёрке никаких зависимостей от размера нет, они есть в FastMM, который стал стандартным только в более новых версиях Delphi.

Так вот я всё это к чему. VCL сама написана "некорректно". То есть она работает с уже удалёнными переменными. Убедиться в этом по-быстрому можно скачав отсюда http://janych.selfip.com/Examples/Delphi/MemoryLeak/ (внизу) мой UdebugMemoryLeak.pas (указать первым в uses dpr-файла) и включив forceViolations:=true;

Ссылка, к сожалению, битая, посмореть ваш пример не могу, но о том, что VCL работает с уже удалёнными переменными, я сам тоже писал: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1153 Правда, я, видимо, рассмотрел не ту ситуацию, о которой пишете вы.


07-03-2009 16:22
Думаю, не совсем так. Думается, что приложение сразу берёт большой кусок памяти у системы, а потом в этом большом куске резервируются участки через new/getMem/realloc. Там есть ещё вроде как различия в зависимости от размеров создаваемых переменных. Для "мелких" используется участок памяти, который системе вообще не возвращается, пока программа не завершится. Хотя я уже не помню, давно разбирался, и только с "семёркой".

Так вот я всё это к чему. VCL сама написана "некорректно". То есть она работает с уже удалёнными переменными. Убедиться в этом по-быстрому можно скачав отсюда http://janych.selfip.com/Examples/Delphi/MemoryLeak/ (внизу) мой UdebugMemoryLeak.pas (указать первым в uses dpr-файла) и включив forceViolations:=true;

В результате удаляемые переменные будут сразу же затираться значениями $FF, и во время CreateForm полезут исключения. Проверял на Делфи 7 (для других модуль может и не работает).


05-03-2008 00:14
сообщение от автора материала
Недавно первый раз прочитал статью, я начинающий, скачал примеры. В примере ButtonDel код, убивающий кнопку "в лоб", работоспособен.
Кто-нибудь может объяснить?


Это связано с особенностями работы менеджера памяти Delphi. Он нередко придерживает освобождённую память, не возвращая её сразу системе, чтобы потом иметь возможность быстрее выделить её снова, когда она ещё для чего-то понадобится. Чтобы не снижать производительность, освобождённая память не очищается. В данном случае это означает, что в освобождённой памяти продолжают лежать данные, составляющие уже удалённый объект Button1, поэтому код VCL, обращающийся к этим данным, не замечает удаления и продолжает работать. Но то, вернёт ли менеджер памяти системе освобождённую память или нет, зависит от предыстории выделения и освобождения памяти, которая в большой сложной программе плохо предсказуема. Там вполне можно получить Access violation.

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


04-03-2008 17:51
Недавно первый раз прочитал статью, я начинающий, скачал примеры. В примере ButtonDel код, убивающий кнопку "в лоб", работоспособен.
procedure TForm1.Button1Click(Sender: TObject);
  begin
   Button1.Free
  end;
Кто-нибудь может объяснить?


17-11-2007 16:25
>>>2Geo: Если это тот же Борис Телеснин, что и пользовательс с ID=4922, то, скорее всего, это действительно такая манера общения :(undefined

Вы ж вроде не особо хотели общаться(типа писали не для меня и все такое). Откуда такой интерес взялся? Неужто сильно фотонами зацепил?
Я это я. Просто забыл пароль да и почту давно поменял. Я не бурбаки. Имя и фамилия соотвествуют паспорту.


17-11-2007 16:20
>>>Почему SetWindowLong не подходит, я объяснил в статье: первые несколько сообщений окно получает ещё до завершения работы CreateWindow(Ex), т.е. до того, как может быть вызвана SetWindowLong.undefined

Не понял ваших возражений здесь - я говорил о варианте замены MakeObjectInstance на  
SetWindowLong. И то и другое вызывается после CreateWindow. То есть конешна все правильно - только  не по делу.


>>>Лично я не могу предложить ни одного более универсального варианта обработки сообщений с сохранением эффективности, чем тот, который реализован в VCL.undefined

Все таки универсальность и эффективность - разные вещи. Назвать код, создающий другой код универсальным - язык не повернется. Например в AtlMFC ( msvc ) для этих целей используется CWnd::FromHandle, и ничо никто еще не жаловался что MFC-шная гуя тормозит по пустому...
Канешна там не линейный поиск а хэш, но ведь дело не в этом(ясно что дельфовый вариант быстрее). Дело как раз в том- настолько ли это быстрее, что стоило бы жертвовать универсальностью?. Почему то, создатели MFC не рискнули создавать execute-read-write страницы памяти. Вот попробуйте предложить варианты почему?

ЗЫ.Все ж таки не первый раз вы мешаете мух с котлетами.



17-11-2007 14:56
>>>Почему SetWindowLong не подходит, я объяснил в статье: первые несколько сообщений окно получает ещё до завершения работы CreateWindow(Ex), т.е. до того, как может быть вызвана SetWindowLong.
А насчёт массива - вы ходь представляете, сколько сообщений получает окно? И сколько
процессорного времени было бы потрачено впустую, если каждый раз при обработке искать окно? Лично я не могу предложить ни одного более универсального варианта обработки сообщений с сохранением эффективности, чем тот, который реализован в VCL. Может быть, вы можете?undefined

Тут либо вы меня не поняли либо за дурака держите( не надо). И первое и второе предполагает что к моим возражениям вы отнеслись гораздо менее серьезно, чем к слову "бред", (что кстати отчасти объясняет его использование).
Мои возражения касались только  ваших пояснений - относительно необходимости введения данного механизма (создания процедуры), а именно "...Задача этой динамически созданной процедуры - передать управление тому методу, который был указан при вызове MakeObjectInstance (таким образом, различные оконные процедуры, сформированные этой функцией, отличаются только тем, какой метод они вызывают)...."   Ну где здесь хоть слово про быстродействие? Ну где спрашивается в тексте статьи чоть слово про скорострельность которая достигается только за счет применения самомодифицируемого кода  Или вы действительно считаете, что процедура создающая процедуру необходима потому, что (цитирую) первые несколько сообщений окно получает ещё до завершения работы CreateWindow(Ex) ? или Задача этой динамически созданной процедуры - передать управление
Ну уж если вы до такой степени подробности описали механизм, так и объяснили бы - почему он!!!! Эта ж пара строчек! Как по вашему начинающий программист ответит на вопрос почему он?
чтоб сделать jmp?
Повторюсь еще раз - динамический код конкретно решает задачу преобразования хендла в this. Для решения задачи "передачи управления" применять динамический код нет никакой необходимости.

>>>Это лично я вам чем-то досадил, что вы себе такое позволяете, или это ваша обычная манера общения?undefined

Упаси г. Просто - "что думаю то и говорю". Можно в принципе сказать - что это и есть манера общения.
В реальной жизни это слабо применимо - за что инету и спасибо.
Подумал - что должен был сперва проверить сам , а уж потом "заставлять" проверять вас. Попутно выяснил - что вы не склонны к догматизму - опять же респект. Вообщем - ничего личного.

>>>(не знаю ваш возраст, поэтому на всякий случай поясню, что это цитата из Ленина). undefined
Возраст не имеет значения,ибо я в любом возрасте про Ленина столько не знал.


29-10-2007 01:25
>>> <...> или это ваша обычная манера общения?
Если это тот же Борис Телеснин, что и пользовательс с ID=4922, то, скорее всего, это действительно такая манера общения :(
 Geo


29-10-2007 00:46
сообщение от автора материала
Борису Телеснину:

если бы задача состояла в этом, то вролне хватило бы и SetWindowLong на одну процедуру для всех экземпляров класса. И вообще не было бы нужды в "самомодификации кода", просто по ващей логике преобразование "HW(хэндл окна) ->указатель на объект" вы бы спокойно сделали в процедуре общей для всего класса каким нибудь поиском в массиве.

Почему SetWindowLong не подходит, я объяснил в статье: первые несколько сообщений окно получает ещё до завершения работы CreateWindow(Ex), т.е. до того, как может быть вызвана SetWindowLong. А насчёт массива - вы ходь представляете, сколько сообщений получает окно? И сколько процессорного времени было бы потрачено впустую, если каждый раз при обработке искать окно? Лично я не могу предложить ни одного более универсального варианта обработки сообщений с сохранением эффективности, чем тот, который реализован в VCL. Может быть, вы можете?

из чего я делаю вывод что дельфю писали не вы

Предыдущее своё сообщение вы начали со слова "бред", здесь какие-то подколки насчёт авторства VCL, на которое я никогда не претендовал, в сообщение с извинениями вы вставили замечание о том, что заставили меня лишний раз программировать, которое "по форме правильное, по сути издевательство" (не знаю ваш возраст, поэтому на всякий случай поясню, что это цитата из Ленина). Это лично я вам чем-то досадил, что вы себе такое позволяете, или это ваша обычная манера общения?


28-10-2007 16:02


Антон:"Прежде чем называть бредом то..."
Приношу свои искренние извинения ввиду ваше правоты по факту моих не менее искренних заблуждений.
Отдельные извинения за то что заставил вас лишний раз программировать.

Сильно не пинайте...



28-10-2007 15:08
сообщение от автора материала
Борис Телесин:

Прежде чем называть бредом то, что я написал, объясните, что означает фраза "The function dispatches incoming sent messages until a posted message is available for retrieval" в описнии функции GetMessage.

Минимальный цикл обработки сообщений обязан включить вызов DispatchMessage( кроме GetMessage)

Абсолютно точно. Можете ещё раз прочитать статью и убедиться, что так я и написал. Без DispatchMessage не смогут обрабатываться сообщения, посланные с помощью PostMessage, а обрабатывать их необходимо.

Проверить это проще пареной репы- вызвать sendMessage,  из другого потока. При этом поставить точку останова в обработчике сообщения формы и сразу после вызова GetMessage

Специально поставил такой эксперимент. Нить такая:

unit Unit2;

interface

uses
  Windows, Messages,Classes;

const WM_TEST = WM_USER + 1;

type
  TTestThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

uses Unit1;

{ TTestThread }

procedure TTestThread.Execute;
begin
  repeat
   SendMessage(Form1.Handle, WM_TEST,0,0);
   Sleep(500)
  until False
end;

end.



Обработчик сообщения такой:

procedure TForm1.WMTest(var Msg:TMessage);
begin
  Label1.Caption:=IntToStr(Random(1000))
end;



Точку останова поставил в TPallication.ProcessMessage на вызове DispathMessage (чтобы это стало возможно, включил опцию Use Debug DCUs). Условие на точку останова наложил Msg.Message = WM_USER + 1. Останов не происходил, хотя текст Label1 менялся. Для чистоты эксперимента заменил SendMessage на PostMessage, и точка останова начала срабатывать. Вы этот эксперимент имели ввиду? Так он ваши же слова и опровергает.

Так что я жду от вас либо дальнейших разъяснений, либо извинений за слово "бред".


28-10-2007 14:57
>>>Функция MakeObjectInstance динамически формирует новую оконную процедуру и возвращает указатель на неё (таким образом, любое VCL-приложение содержит самомодифицирующийся код). Задача этой динамически созданной процедуры - передать управление тому методу, который был указан при вызове MakeObjectInstance (таким образом, различные оконные процедуры, сформированные этой функцией, отличаются только тем, какой метод они вызывают).undefined
Антон, если бы задача состояла в этом, то вролне хватило бы и SetWindowLong на одну процедуру для всех экземпляров класса. И вообще не было бы нужды в "самомодификации кода", просто по ващей логике преобразование "HW(хэндл окна) ->указатель на объект" вы бы спокойно сделали в процедуре общей для всего класса каким нибудь поиском в массиве. Но поиска там нет,а есть самомодифицирующийся код основное назначение которого - в преобразовании "HW ->указатель на объект" из чего я делаю вывод что дельфю писали не вы...  


28-10-2007 14:30
>>>Антон:"При любом способе использования GetMessage и PeekMessage возвращают наружу только сообщения из очереди посланных (post) сообщений. Ещё существует очередь отправленных (send) сообщений, и эта очередь обрабатывается целиком внутри GetMessage или PeekMessage независимо от их параметров"undefined
Антон это бред, внутри GetMessage и PeekMessage вызываются только алерты, хуки, и completionproc. Сообщения эти вызовы никогда не обрабатывали. Минимальный цикл обработки сообщений обязан включить вызов DispatchMessage( кроме GetMessage) (  http://msdn2.microsoft.com/en-us/library/ms644928.aspx). Именно DispatchMessage вызывает оконную процедуру. Это известно каждому кто хоть раз запускал цикл сообщений сам.  Проверить это проще пареной репы- вызвать sendMessage,  из другого потока. При этом поставить точку останова в обработчике сообщения формы и сразу после вызова GetMessage.  Очередь сообщений всегда одна на один поток(то есть их не 2 на поток), при этом появляется(создается) она только после первого вызова Peek ,Get. Вызов send не связанный с переходом между потоками, в очереди просто не нуждается, и как следствие проскакивает мимо цикла сообщений. Различные виды сообщений имеют разные приоритеты (подробности у Рихтера), для практики надо помнить что PostMessage - будет иметь наивысший приоритет, а WM_PAINT наинизший, то есть вредно например посылать PostMessage(WM_PAINT), или при долгой обработке сообщения и частой его посылке через Post можно просто наметртво заблокировать все остальные сообщения.




05-10-2007 02:19
Для Антона Григорьева:
Было бы неплохо, если бы ты подсказал как написать код, который бы позволил проверить что существует действительно две очереди у каждого потока, одна для помещенных(PostMessage), а другая для отправленных(SendMessage).

Или же как это можно вообще проверить, может вообще одна очередь с флагами "посланное", "отправленное". А гуру вообще задал бы вопрос: "Почему отправленное сообщение следует считать приритетней чем посланное?"


05-10-2007 01:20
сообщение от автора материала
Просьба прояснить что же такого делают GetMessage\PeekMessage что TranslateMDISysAccel и др. немогут получить эти сообщения?

При любом способе использования GetMessage и PeekMessage возвращают наружу только сообщения из очереди посланных (post) сообщений. Ещё существует очередь отправленных (send) сообщений, и эта очередь обрабатывается целиком внутри GetMessage или PeekMessage независимо от их параметров.

Т.е. получается после PeekMessage сообщения можно получить !

Нет, в данном случае PeekMessage просто оставляет сообщение в очереди посланных сообщений, и при следующем вызове GetMessage или PeekMessage будет возвращено оно же. К очереди отправленных сообщений это не имеет никакого отношения.

А смысл этого кода в VCL (такое появилось, кстати, только в BDS 2006) в том, что с помощью PeekMessage извлекается информация о самом верхнем сообщении в очереди посланных, но само сообщение при этом не удаляется. Затем по дескриптору окна - получателя этого сообщения определяется, использует ли данное окно кодировку ANSI или Unicode, и затем с помощью PeekMessageA или PeekMessageW извлекается это же сообщение и передаётся на обработку. Но это никак не помогает получить сообщение из очереди отправленных сообщений.


05-10-2007 00:58
В статье написано:

Примечание: так как сообщения, отправленные окну, передаются оконной процедуре напрямую либо диспетчеризуются внутри GetMessage или PeekMessage, эти сообщения не попадают в функции TranslateMDISysAccel, TranslateAccelerator и TranslateMessage.

Просьба прояснить что же такого делают GetMessage\PeekMessage что TranslateMDISysAccel и др. немогут получить эти сообщения?

Почему смутило?
Я глянул в VCL и увидел:

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
//....
  if PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE) then
  begin


Т.е. получается после PeekMessage сообщения можно получить !


27-09-2007 22:42
2 АГ:
Есть примечание:
Примечание: путаницу между понятием родителя и владельца усиливает то, что в MSDN по отношению к окнам тоже используются термины owner и owned (принадлежащий), однако это не имеет никакого отношения к владельцу в понимании VCL. Если окно имеет стиль WS_Child, то оно...
Я бы порекомендовал бы его немного изменить, чересчур сложно читать ;) Я так и не понял, уже 2й день перечитываю, но так и не понял ;)))


03-10-2006 22:16
"Компонент-на форму-кидатель" - это кликуха, изобретенная горе программистами (или одним из них), которые не могут написать нужные компоненты. Попробуйте Шумахеру заявить, что он "педале-на акселератор-нажиматель". Просто эти горе программисты не знают предметную область. А без этого хоть ты наизусть выучи API всех операционных систем, знай ты досконально всю подноготную процесса создания компонент, - все равно ничего путного не напишешь. Зато будешь распространяться на тему о том, как использовать API в VCL. Очень плохо, когда есть только такие компоненты, где без API не можешь обойтись. Архитектору сложных систем приходится заниматься производством "кирпичей". Позор!!!


03-10-2006 05:51
сообщение от автора материала
А может это миф, которым пугают детей?:-) Ни разу не видел таких в жизни.:-)

В жизни я их тоже, к счастью, не видел. А вот в интернете вопросов от них - предостаточно. Так что одно из двух: либо они действительно существуют, либо кто-то в массовом порядке создаёт виртуальные личности, от имени которых и задаёт такие вопросы. Мне почему-то первый вариант кажется более вероятным :)


03-10-2006 05:27
"компоненто-на-форму-кидатель"

А может это миф, которым пугают детей?:-) Ни разу не видел таких в жизни.:-)


28-09-2006 03:28
Отличная статья!
Серьезный анализ стыка Delphi и  WinAPI. В книгах по Delphi подобного не видел.
Спасибо, Антон Григорьев!


27-01-2006 06:36
Антон Григорьев:
Спасибо, за ваши статьи, читаю с большим интересом. Даже если я и не буду использовать материал, изложеный Вами, я рад, что смог расширить свой кругозор и теперь лучше представляю себе работу VCL.  


28-10-2005 15:17
Чудес всё-таки не бывает. Как выяснилось, описанное поведение наблюдается только на картах NVIDIA и только в одной "партии" компов. Короче всё дело было в кривом драйвере, после установки свежескачанного драйвера всё встало на свои места: DDB быстрее в 15-25 раз. Эффект "запаздывания" на NVIDIA полностью отсутствует, у меня он только на ATI проявляется. И вообще карты ATI показали в этих тестах намного лучшие результаты, в том числе и за счёт асинхронной работы в режиме DDB.
 DRON


28-10-2005 07:34
Не все так просто.

Использование 3D/2D заморочек рассчитано в большинстве случаев на ускорение формирования картинки из набора исходных данных, а не тупое копирование заранее подготовленных областей бит по шине.

Почему медленнее? Потому что при DDB происходит аппаратная реализация заморочек, при которой нагружается GPU, в то время как при DIB вы, суете видеокарте готовую картинку.


28-10-2005 07:11
Где-то в настройках Windows я находил запрет на использование аппаратного ускорителя, и даже в каком-то тысяча девятьсот лохматом году этим пользовался - на моей карте глючил Corel Draw, пока я это не отключил. Может быть, в этом дело?
Это дело я в первую очередь проверил, там всё по максимуму. Меня это тоже удивило, в реальной программе использовал DDB, но после этих экспериментов перешёл на DIB и скорость увеличилась (точнее загрузка проца уменьшилась, частота фиксирована на 20fps) почти в ПЯТЬ раз. Но на некоторых компах наоборот упала примерно в 25 раз (проц загружен на 100% и немного тормозит), причём сильнее всего на стареньком ноуте. Судя по всему, по 2D графике современный процессор обгоняет видео-карту или некоторые производители забили на 2D и улучшают только 3D, а на самом деле чёрт его знает, что там творится. Я всем этим тоже не занимался, но чувствую придётся, так как надо научиться выбирать лучший для данной машины формат. Начну со сбора статистики, а то пара компов это несерьёзно для каких либо выводов.
На всех компьютерах, на которых я это тестировал, при относительно небольших количествах повторов измеренное программой время было существенно меньше наблюдаемого.
Там на самом деле разница на константу (около 1-2сек), это легко наблюдать поставив в нужных местах "Windows.Beep(440,10);" и, с помощью ручного секундомера, засекать время между "бипом" и концом "мельтешения". Скорее всего, имеет место аппаратная сериализация вызовов и время задержки зависит от максимального размера очереди в видео-карте. Применение GdiFlush и GdiSetBatchLimit(1) результатов не изменили, настройки карты, тоже (там и нет отдельных 2D настроек).

Уменьшение "Аппаратного ускорения" приводит к замедлению сразу раз в 25. Всё это проявляется только на тех компах где DDB быстрее DIB, на других вообще ничего, ни от чего не зависит (по крайней мере в разы).
 DRON


28-10-2005 06:44
сообщение от автора материала
Мухтар:

А что конкретно вы подразумеваете под 3D/2D-заморочками? Насколько мне известно, главные из "2D-заморочек" - это работа с прямоугольными областями, прежде всего заливка и копирование картинок, так что вывод DDB-изображения - это и есть та самая заморочка, которую должна уметь поддерживать любая уважающая себя видеокарта.


28-10-2005 05:48
Антон Григорьев:

Ничего удивительного в этом нет. Программный вывод подразуемвает скорее всего прямое обращение к памяти видео-карты, который не менялся с времен Дос, в то время как аппаратный рассчитан не на быстрый ввод-вывод, а на Open GL и прочие 3d/2d заморочки

Извиняюсь что влез в ваш разговор :)


28-10-2005 05:09
сообщение от автора материала
DRON:

То, что DDB может выводиться на экран медленнее, чем DIB, оказалось для меня большой неожиданностью. Чтобы аппаратный ускоритель, да ещё и с родным форматом работал медленнее, чем чисто программные алгоритмы... Где-то в настройках Windows я находил запрет на использование аппаратного ускорителя, и даже в каком-то тысяча девятьсот лохматом году этим пользовался - на моей карте глючил Corel Draw, пока я это не отключил. Может быть, в этом дело?

Вообще, с измерением скорости вывода на экран есть и другие чудеса (в комментариях к примеру я об этом написал). На всех компьютерах, на которых я это тестировал, при относительно небольших количествах повторов измеренное программой время было существенно меньше наблюдаемого. Например, видно, что вывод занимает около трёх секунд, а измерения дают полсекунды или даже меньше. Чем больше количество итераций, тем меньше заметна разница. Причём на разных компьютерах разница становилась незаметной при различных количествах итераций. Я измерял время сначала с помощью GetTickCount, потом прешёл на QueryPermormanceCounter - результаты не изменились. Почему так происходит, я так и не понял. То ли видеокарта при обращении к памяти приостанавливает работу процессора, то ли ускоритель работает параллельно с процессором, то ли ещё что - я не знаю, я плохо знаком со всеми этими аппаратными штучками.


26-10-2005 16:00
Хотелось бы сказать пару слов по поводу примера "BitmapSpeed".
Во-первых, фраза "но вывод DDB на экран всегда существенно быстрее, чем DIB" слишком категорична. На NVIDIA MX 400 (другие пока не проверял) скорость вывода на экран 24bit DIB (в вашем примере именно так) примерно в два раза выше, чем вывод DDB (8bit ещё быстрее), а скорость вывода 32bit DIB один в один совпадает с DDB (скорее всего это один и тот же формат).
Во-вторых, не знаете ли вы способ (без проведения тестов конечно) определения, какой тип хранения Bitmap-ов будет быстрее всего работать на заданной видео карте?
 DRON


23-09-2005 02:06
сообщение от автора материала
Анониму:

не нравится вопрос - игнорируй

Не согласен. Почему я не буду игнорировать такие вопросы, я написал здесь: http://www.delphikingdom.com/asp/answer.asp?IDAnswer=35547


23-09-2005 00:35
to Geo
как можно любить-нелюбить или даже недолюбливать человека, которого даже не знаешь и не видел? не нравится вопрос - игнорируй... или желание посмеяться над кем-то настолько непреодолимо? думаешь, что унизив или оскорбив кого-то ты становишься круче и возвышаешься в глазах окружающих? ну не хочет человек учиться, ну и что? может он как человек хороший...
кстати, а я вот недолюбливаю пресмыкающихся...
Сообщение не подписано


22-09-2005 06:24
to SSV:

Есть люди, которые научились бросать компоненты на форму и считают себя крутыми программистами. Считают что этого достаточно.

Есть люди, которые пока умеют только кидать компоненты на форму, но стремятся узнать больше.

Сначала они выглядят одинаково, задавая один и тот же вопрос: "Где найти такой-то компонент". Но вот на предложение сделать такой компонент самостоятельно следуют ответы двух типов. И ответ позволяет достаточно точно отнести автора либо к первым, либо ко вторым.

Вторые сразу начинают расспрашивать, как это сделать, где прочитать.

А первые продолжают нудно тянуть: "А готового компонента нет?".

Вот этих первых Антон, мягко выражаясь, недолюбливает (да и не он один) и называет компоненто-на-форму-кидателями. Так как термин он сочинил сам, то такого ресурса Вы не найдете. Разве что Антон разместит в интернете словарь собственных терминов :-)
 Geo


22-09-2005 02:03
Антон Григорьев:
<Я ещё раз обясняю: компоненто-на-форму-кидатель - это тот, кто считает, что кидать на форму компоненты - этого вполне достаточно>
почему тогда в списке литературы нет ссылки на ресурс, в котором можно найти определение термина "компоненто-на-форму-кидатель"?
 SSV


21-09-2005 09:08
Отличная статья!
Такой концентрации полезных сведений в сочетании с доступностью изложения и качеством информации я не встречал ни в одной книге по Delphi.
Спасибо, Антон.


21-09-2005 07:43
сообщение от автора материала
SSV:
Я ещё раз обясняю: компоненто-на-форму-кидатель - это тот, кто считает, что кидать на форму компоненты - этого вполне достаточно. Если же человек умеет только кидать компоненты на форму, но понимает, но при этом понимает, что это ещё не программирование - он не компоненто-на-форму-кидатель, он - начинающий программист, т.е. человек, вполне достойный уважения. И я это в предыдущем сообщении ясно сказал. Не понимаю, откуда такое стремление найти в моих словах какой-то скрытый оскорбительный смысл.


21-09-2005 07:31
Антон Григорьев:
<А статья ориентирована на тех, кто уже понимает, что кроме использования готовых компонентов можно делать ещё много чего, но пока не знает, как это делать>
и пока еще является "КНФК"?
 SSV


21-09-2005 07:06
сообщение от автора материала
SSV:

Это кого же я оскорбил? "Компоненто-на-форму-кидателей"? Так эта статья точно не на них рассчитана. "Компоненто-на-форму-кидатель" в моём понимании - это человек, который считает, что программирование в Delphi исчерпывается киданием на форму компонентов и установлением взаимосвязей между ними, а все нестандартные задачи пытается решить поиском подходящих компонентов в интеренете. Таких людей я не уважаю, и если даже оскорбил их, нисколько в этом не раскаиваюсь. А статья ориентирована на тех, кто уже понимает, что кроме использования готовых компонентов можно делать ещё много чего, но пока не знает, как это делать. Таких людей оскорблять у меня нет никакого желания - все мы через это прошли, никто с умением программировать не родился. Одним словом, я руководствуюсь пословицей "не стыдно не знать, стыдно не учиться". А сейчас, к сожалению, очень много развелось таких "программистов", которые именно не учатся.


21-09-2005 00:33
Статья хорошая, только вот заключение... интересно, для кого эта статья была написана? не для тех ли, кого автор в своём заключении вот так запросто взял и оскорбил?
 SSV


15-09-2005 05:46
Классно написано!
Очень многое прояснилось в структуре VCL и использовании сообщений в Delphi.
Большое спасибо!
Сообщение не подписано


09-09-2005 08:49
Антон, спасибо!
Все очень хорошо написано.


08-09-2005 03:56
Очень хорошая статья.
Думаю, буду возвращаться к ней не раз.


08-09-2005 02:23
сообщение от автора материала
Так, волна комментариев закончилась, пора отвечать :)

Анониму:

Хотелось бы что бы в демо примерах появились проекты которые бы использовали классы TCoordLabel и TLine (без их предварительной установки в делфи), т.е. экземпляры классов создавались бы кодом.

Честно говоря, не вижу большого смысла в этом. Эффектность этих примеров (особенно TLine) во многом определяется тем, что их можно установить в палитру компонентов и бросить на форму - без этого впечатление от них будет неполным. Так что пока я не вижу необходимости делать такие проекты. Но ещё подумаю об этом.

checker'у:

Второе утверждение не совсем неверно, так делается "как правило", но не всегда. Владельца компонента (свойство Owner) можно поменять вручную с помощью методов InsertComponent() и RemoveComponent().

Согласен, тут я поторопился с утверждением. При случае подправлю.

Константину Цветкову:

думаю, что идти нужно от WinAPI к Delphi. То есть, сначала изучить WinAPI (в  плавании по сухому), а потом смотреть как это реализуемо в Dephi.

В общем-то, Geo уже ответил. Добавлю только, что в 99% случаев использование API при программировании на Delphi сводится именно к API-вставкам в VCL-приложение. Вот и давайте учиться тому, что мы потом будем применять на практике - так будет легче добраться до основ, с которых вы предлагаете начать.


05-09-2005 07:24
>>> Я, например, узнал WinAPI раньше Delphi, поскольку программировал тогда на VO, FiveWin.
А я программировать в машинных кодах стал раньше, чем на ассемблере :-) Но это же не повод, рекомендовать данный подход в качестве стандарта для обучения :-)
 Geo


05-09-2005 07:13
2Geo: Я, например, узнал WinAPI раньше Delphi, поскольку программировал тогда на VO, FiveWin.


05-09-2005 04:31
Статья понравилась. Если по работе с графикой существут прекрасная книга Фень Юань, то здесь впервые прочитал как происходит работа со стоками.

PAV
Сообщение не подписано


05-09-2005 03:24
to Константин Цветков
Изучать с нуля Win API?! Удовольствие ниже среднего. Пока не наберешь критическую массу знания, программу не напишешь. Лучше уж слепить программку на Delphi, а потом совершенствовать ее, внедряя последовательно функции из Win API.
 Geo


05-09-2005 03:19
Статья хорошая, но думаю, что идти нужно от WinAPI к Delphi. То есть, сначала изучить WinAPI (в  плавании по сухому), а потом смотреть как это реализуемо в Dephi.


02-09-2005 02:26
>>> Свойство Owner доступно только для чтения. Владелец компонента задаётся один раз при вызове конструктора и остаётся неизменным на протяжении всего жизненного цикла компонента.

Второе утверждение не совсем неверно, так делается "как правило", но не всегда. Владельца компонента (свойство Owner) можно поменять вручную с помощью методов InsertComponent() и RemoveComponent(). Например, можно создать компонент с Owner = nil в конструкторе, а позже определить для него нового Owner. В исходниках Delphi есть несколько таких примеров.


02-09-2005 00:20
Змечательная статья проясняет многие "тонкие" места при работе с API.

Хотелось бы что бы в демо примерах появились проекты которые бы использовали классы TCoordLabel и TLine (без их предварительной установки в делфи), т.е. экземпляры классов создавались бы кодом.
Сообщение не подписано


01-09-2005 23:27
>>>Мне кажется, что зацикливаться на API нельза, поскольку оно есть продукт микрософта
Вот это перл! :-) Позвольте Вас спросить, а Вы не под Windows программируете? Или может думаете, что Ваши программы не вызывают Win API?
Статья отличная!


10-09-2002 01:41
Мне кажется, что зацикливаться на API нельза, поскольку оно есть продукт микрософта, который не славится правильной работой своих продуктов. Иногда можно найти необходимое с списке методов правильно выбранного объекта. Но только иногда. Ярким примером может служить печать из TWebBrowser которую кроме как на API осуществить не возможно. НО опять оно не совсем работает- не получается печатать на сетевые принтеры, хотя оно может и не критично:)

ЗЫЖ Решение описанно проблемы можно найти на сайте Акжана. Ищите и обрящете!


13-05-2002 09:35
Молодец Антон !
Довольно неплохо написано, некоторые вещи для меня встали на свои места, хотя я не считаю себя новичком в API.


22-03-2002 04:43
Results 0-0 of about 0 containing "сайт http://www.delphikingdom.com"  

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

Sorry, no results were found containing "сайт http://www.delphikingdom.com"


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Вода мокрая или сухая?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования