tag:blogger.com,1999:blog-1702873441071265539.post6789219656319400252..comments2023-05-29T19:02:20.570+03:00Comments on Блог GunSmoker-а: Задачка №6GunSmokerhttp://www.blogger.com/profile/15611696588191431330noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-1702873441071265539.post-62870157747674986292011-02-11T22:31:03.771+03:002011-02-11T22:31:03.771+03:00Собственно, багов никаких нет. Единственное, что е...Собственно, багов никаких нет. Единственное, что есть, это неполное описание параметров функции GetObject в Platform SDK, например, что требуется выровненный буфер (по моему мнению)Igor Schevchenkohttps://www.blogger.com/profile/06503541755579898125noreply@blogger.comtag:blogger.com,1999:blog-1702873441071265539.post-17540173947519707602011-02-10T11:33:00.123+03:002011-02-10T11:33:00.123+03:00При выключенной оптимизации компилятор резервирует...При выключенной оптимизации компилятор резервирует место на стеке под Value, размером в один байт. Так как Windows.TBitmap объявлена как packed record, то компилятор не заботится о выравнивании этой переменной и она располагается сразу за местом для Value, по нечетному адресу. <br />При включенной оптимизации на стеке размещается единственная переменная типа Windows.TBitmap, адрес которой, естественно, выровнен на 4-х байтовую границу.Igor Schevchenkohttps://www.blogger.com/profile/06503541755579898125noreply@blogger.comtag:blogger.com,1999:blog-1702873441071265539.post-90500748245908138912011-02-08T20:55:47.650+03:002011-02-08T20:55:47.650+03:00"Если входной параметр BitmapHandle: HBITMAP ..."Если входной параметр BitmapHandle: HBITMAP получен через CreateDIBSection, то GetObject попытается в BitmapInfo: Windows.TBitmap записать информацию типа Windows.TDIBSection, что немного больше по размеру. "<br /><br />if Object type is HBITMAP returned from a call to CreateDIBSection then Data written to buffer is DIBSECTION, if cbBuffer is set to sizeof(DIBSECTION), or BITMAP, if cbBuffer is set to sizeof(BITMAP) <br /><br />(Platform SDK)<br /><br />Код работает с включенной оптимизацией и не работает с выключенной. На мой взгляд, причина в том, что адрес буфера не выровнен на границу 4-х байт в случае отключенной оптимизации (Delphi 2006).<br /><br />Изменив код на<br /><br />procedure Test(const BitmapHandle: HBITMAP; Value: Boolean);<br />var<br /> RetValue: LongInt;<br /> BitmapInfo: Windows.TBitmap;<br />begin<br /> if not Value then<br /> Exit;<br /> FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);<br /> RetValue := Windows.GetObject(BitmapHandle, SizeOf(BitmapInfo), @BitmapInfo);<br /> if RetValue = 0 then<br /> ShowMessage('FAIL')<br /> else<br /> ShowMessage('SUCCESS');<br />end;<br /><br />он заработал вне зависимости от настроек оптимизации.Igor Schevchenkohttps://www.blogger.com/profile/06503541755579898125noreply@blogger.comtag:blogger.com,1999:blog-1702873441071265539.post-17035708090334829152011-02-08T13:34:11.144+03:002011-02-08T13:34:11.144+03:00Если входной параметр BitmapHandle: HBITMAP получе...Если входной параметр BitmapHandle: HBITMAP получен через CreateDIBSection, то GetObject попытается в BitmapInfo: Windows.TBitmap записать информацию типа Windows.TDIBSection, что немного больше по размеру.Anonymoushttps://www.blogger.com/profile/10171235556125782587noreply@blogger.comtag:blogger.com,1999:blog-1702873441071265539.post-51662804638286753912011-02-08T04:10:44.020+03:002011-02-08T04:10:44.020+03:00Совсем недавно столкнулся с подобным. Хотел сделат...Совсем недавно столкнулся с подобным. Хотел сделать BitmapInfo полем класса (точнее только размеры), но чудесным образом GetObject в его конструкторе возвращало 0. Вынес все в гдобальные переменные - заработало:<br /><br />var<br /> ArrowBitmap: HBITMAP = 0;<br /> ArrowBitmapSize: TSize = (cx: 0; cy: 0);<br /><br />procedure LoadArrowBitmap;<br />var<br /> Bitmap: Windows.Bitmap;<br />begin<br /> if (ArrowBitmap = 0) then<br /> begin<br /> ArrowBitmap := LoadBitmap(HInstance, 'BTNMNU');<br /><br /> if (ArrowBitmap <> 0) and<br /> (GetObject(ArrowBitmap, SizeOf(Bitmap), @Bitmap) <> 0) then<br /> begin<br /> ArrowBitmapSize.cx := Bitmap.bmWidth;<br /> ArrowBitmapSize.cy := Bitmap.bmHeight;<br /> end;<br /> end;<br />end;<br /><br />{ TMySplitButton }<br /><br />constructor TMySplitButton.Create(AOwner: TComponent);<br />begin<br /> inherited Create(AOwner);<br /> LoadArrowBitmap;<br /> UpdateSplitWidth;<br />end;<br /><br />PS. Ничего не понял :)Anonymousnoreply@blogger.com