Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Поймать изображение кнопки


Автор: drinkOut 18.5.2005, 00:13
Собственно сабж: я ловлю - оно не ловится... smile
Очень хотелось бы узнать, в чём причина... smile
smile
Код

var
  hTaskbar : HWND;
  StartBtn : HWND;
  ButtonDC : HDC;
  Bitmap   : TBitmap;
begin
  hTaskbar := FindWindow('Shell_TrayWnd', nil);
  StartBtn := FindWindowEx(hTaskbar, 0, 'Button', nil);
  ButtonDC := GetDC(StartBtn);
  try
    Bitmap := TBitmap.Create;
    Bitmap.Handle := ButtonDC;
    if Bitmap <> nil then
      Canvas.Draw(10, 10, Bitmap)
    else
      MessageDlg('Empty Bitmap', mtWarning, [mbOk], 0);
  finally
    Bitmap.Free;
  end;
end;

Сообщение 'Empty Bitmap' у меня не появляется, а картинка на форме всё равно не рисуется. smile

Автор: s-mike 18.5.2005, 00:31
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  hTaskbar : HWND;
  StartBtn : HWND;
  ButtonDC : HDC;
  Bitmap   : TBitmap;
begin
  hTaskbar := FindWindow('Shell_TrayWnd', nil);
  StartBtn := FindWindowEx(hTaskbar, 0, 'Button', nil);
  ButtonDC := GetDC(StartBtn);
  Bitmap := TBitmap.Create;
  try
    Bitmap.Width := 32;
    Bitmap.Height := 32;
    BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, ButtonDC, 0, 0, SRCCOPY);
    if (Bitmap.Width > 0) and (Bitmap.Height > 0) then
      Canvas.Draw(10, 10, Bitmap)
    else
      MessageDlg('Empty Bitmap', mtWarning, [mbOk], 0);
  finally
    Bitmap.Free;
  end;
  ReleaseDC(ButtonDC);
end;

Автор: jack128 18.5.2005, 00:40
Утечки памяти есть ;)

Код

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  hTaskbar : HWND;
  StartBtn : HWND;
  ButtonDC : HDC;
  TempCanvas: TCanvas;
  TempRect: TRect;
begin
  hTaskbar := FindWindow('Shell_TrayWnd', nil);
  Win32Check(hTaskbar <> 0);
  StartBtn := FindWindowEx(hTaskbar, 0, 'Button', nil);
  Win32Check(StartBtn <> 0);
  ButtonDC := GetDC(StartBtn);
  Win32Check(ButtonDC <> 0);
  try
    TempCanvas := TCanvas.Create;
    try
      TempCanvas.Handle := ButtonDC;
      TempRect := Rect(0, 0, PaintBox1.Width, Paintbox1.Height);
      PaintBox1.Canvas.CopyRect(TempRect, TempCanvas, TempRect)
    finally
      TempCanvas.Handle := 0;
      TempCanvas.Free;
    end;
  finally
    ReleaseDC(StartBtn, ButtonDC); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  end;
end;

Автор: drinkOut 18.5.2005, 00:45
http://rulezman.multik.org/31.gif
jack128, supreme! smile Я только не понимаю, что не так в моей версии кода?.. smile
Пока не скажешь, плюс не поставлю! smile

Автор: jack128 18.5.2005, 00:46
Bitmap.Handle - это хендл битмапа, а не канвы. Это разные объекты.

Автор: s-mike 18.5.2005, 00:49
Цитата(drinkOut @ 18.5.2005, 00:45)
Я только не понимаю, что не так в моей версии кода?

1. Создание класса внутри блока try..finally
2.
Цитата(jack128 @ 18.5.2005, 00:40)
Утечки памяти есть ;)

Вот про ReleaseDC и я забыл.

Автор: drinkOut 18.5.2005, 17:21
Цитата(s @ 18.5.2005, 00:49)
Создание класса внутри блока try..finally
А чем это плохо? smile

Автор: Rennigth 18.5.2005, 17:43
Цитата

Цитата (s-mike @ 18.5.2005, 00:49)
Создание класса внутри блока try..finally

А чем это плохо? 

ни чем... просто создание класса теоритически(я с этим не соглачен smile) не может вызвать исключения, вот и принято вначале создавать класс потом try а в finally уничтожать.

одно исключение TAdoConnection и да и конструктор своих классов легко может глючить,
все по ситуации.

Автор: s-mike 18.5.2005, 23:29
Цитата(Rennigth @ 18.5.2005, 17:43)
ни чем... просто создание класса теоритически(я с этим не соглачен smile) не может вызвать исключения, вот и принято вначале создавать класс потом try а в finally уничтожать.

Да прям таки ничем, если класс не будет создан в блоке try..finally в результате какой-то ошибки, то в блоке finally получится большооой AV.

Автор: Rennigth 19.5.2005, 10:16
s-mike
Цитата

Да прям таки ничем, если класс не будет создан в блоке try..finally в результате какой-то ошибки, то в блоке finally получится большооой AV.

это с чего это? ты смотрел код free?
Код

  if Assigned(self)  then
    self.destroy;

и как это может вызвать AV

Автор: jack128 19.5.2005, 10:29
Цитата(Rennigth @ 19.5.2005, 10:16)
и как это может вызвать AV

а с чего ты взял, что в переменной Bitmap изначально nil будет?
вот в таком коде AV не будет
Код

Bitmap := nil;
try
  Bitmap := TBitmap.Create;
finally
  Bitmap.Free;
end;


а в твоем вполне

Автор: Rennigth 19.5.2005, 10:44
jack128
Цитата

  Bitmap := nil;

все объекты по умолчанию nil
Цитата

а в твоем вполне

каком моем smile я вроде только напомнил код из system.pas.
Цитата

Bitmap := nil;
try
Bitmap := TBitmap.Create;
finally
Bitmap.Free;
end;


я об этом и говорю... что все по обстоятельством но принято писать
Код

  Bitmap := TBitmap.Create;
  try
    Bitmap.LoadFromResourceID(0, 666) ;
  finally
    Bitmap.Free;
  end;

этот код в любом случае нормально отработает, но есть ситуации когда один Create надо в try except заключать...




Автор: s-mike 19.5.2005, 10:52
Цитата(Rennigth @ 19.5.2005, 10:44)
этот код в любом случае нормально отработает, но есть ситуации когда один Create надо в try except заключать...

Никогда не надо! Это грубая ошибка! Вот представь, что в конструкторе произойдет ошибка. Тогда в переменную не будет занесен адрес класса или будет занесен ошибочный. А по умолчанию все классы не равны nil, попробуй запустить:
Код

procedure TForm1.FormCreate(Sender: TObject);
var
  Bmp: TBitmap;
begin
  if Bmp = nil then
    ShowMessage('nil')
  else
    ShowMessage('not nil');
end;

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

Автор: Rennigth 19.5.2005, 11:24
s-mike
я привык проверять существование объекта на Assigned,
ты попробуй запустить
Код

 procedure TForm1.FormCreate(Sender: TObject);
var
  Bmp: TBitmap;
begin
  if Assigned(bmp) then
   ShowMessage('nil')
  else
    ShowMessage('not nil');
end; 


попробуй хотябы создать TADOConnection если у проекта небыло
Application.init (одит из примеров) а если у тебя класс с прооверайженным конструктором и там ошибка...

Автор: jack128 19.5.2005, 11:26
Rennigth Assigned проверяет на НЕ равенство nil'у. Так что писать нужно так

Код

  if Assigned(bmp) then
   ShowMessage('not nil')
  else
    ShowMessage('nil');

Автор: Rennigth 19.5.2005, 11:33
jack128
а ну да...
ЦСКА форева, похмелье... бошка ватная...

Цитата

  все объекты по умолчанию nil

забираю свои слова обратно... интерфейсы рулят(они - то nilы)...






Автор: Vit 19.5.2005, 15:56
Цитата(Rennigth @ 19.5.2005, 01:16)
if Assigned(self)  then
    self.destroy;



А ты этого, в коде когда нибудь поставь два free подряд smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)