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