Конференция "Прочее" » Двойная буфферизация(выдернуто из "Вакансия Delphi программист")
 
  • Игорь Шевченко © (27.03.08 14:14) [200]

    > Вид 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;

    {$R *.dfm}

    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.



    Можешь сам попробовать
  • Игорь Шевченко © (27.03.08 15:12) [201]
    кстати, в программке неверно StockObject судя по всему определяется, но это не страшно
  • oxffff © (27.03.08 22:19) [202]

    > Можешь сам попробовать


    Спасибо конечно. Но я как то и сходу могу установить вид глядя на BC05126E.
    :)

    вот бы удалось расшифровать  ВС. Ну нулевой понятно Stock. А вот остальное. У вас случаем нет информации о битах 25-31?
  • oxffff © (27.03.08 22:22) [203]

    > oxffff ©   (27.03.08 22:19) [202]


    В данном случае BC - это не stock object. Так что то же значит BC. :)
  • Игорь Шевченко © (27.03.08 23:23) [204]
    "Манипулятор объекта 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
  • Игорь Шевченко © (27.03.08 23:32) [205]
    "При анализе структуры манипуляторов GDI в разделе «Поиск таблицы объек-
    тов GDI» нерасшифрованными остались лишь старшие 8 бит. Дополнительные
    эксперименты показывают, что в них хранится счетчик повторного использования — еще одно простое средство проверки манипуляторов. У каждого элемента таблицы объектов GDI первоначальное значение счетчика равно 0. Когда в элемент таблицы заносится информация о новом объекте GDI, его счетчик повторного использования увеличивается (когда значение достигает 255, счетчик снова сбрасывается в 0). Таким образом, когда элемент задействуется впервые, его
    счетчик повторного использования равен 0x01; это относится ко всем стандартным объектам GDI, которые создаются один раз и никогда не удаляются. Если вы удаляете объект GDI и создаете новый объект в том же элементе таблицы, даже при совпадении типов объектов манипуляторы будут отличаться, поскольку значение счетчика повторного использования увеличилось. Все вызовы функций, в которых присутствует исходный манипулятор, завершатся неудачей."
    (с) оттуда же, стр 169.

    К вопросу о том, что такое BC
 
Конференция "Прочее" » Двойная буфферизация(выдернуто из "Вакансия Delphi программист")
Есть новые Нет новых   [134433   +22][b:0.001][p:0.003]