Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.04;
Скачать: CL | DM;

Вниз

TextOut   Найти похожие ветки 

 
D7   (2004-06-14 16:12) [0]

Здравствуйте.
Кто-нибудь объяснит почему код:

procedure TForm1.Button1Click(Sender: TObject);
var
 DC: HDC;
 S: string;
begin
 S:=Memo1.Lines[0];
 DC:=Canvas.Handle;
 TextOut(DC, 10, 10, PChar(S), Length(S));
end;

выодит текст, а код:

procedure TForm1.Button1Click(Sender: TObject);
var
 DC: HDC;
 S: string;
begin
 DC:=Canvas.Handle;
 S:=Memo1.Lines[0];
 TextOut(DC, 10, 10, PChar(S), Length(S));
end;

не выводит. Спасибо.


 
KilkennyCat ©   (2004-06-14 16:31) [1]

TextOut(Canvas.Handle, 10, 10, PChar(S), Length(S));

и не мучайся.


 
D7   (2004-06-14 16:35) [2]

Это я в курсе, но мне интересно было бы получить ответ на вопрос...


 
Piter ©   (2004-06-14 16:44) [3]

Я так понимаю, что примеры отличаются только переменой первой и второй строки? Тогда без разницы и ошибка не здесь кроется...


 
KilkennyCat ©   (2004-06-14 16:47) [4]


> Piter ©   (14.06.04 16:44) [3]

текст действительно не выводится. DC не меняется. Если S просто присваивать "gvghkl", а не строку Мемо, то все работает.


 
Piter ©   (2004-06-14 16:50) [5]

интересно... пойду пускать Дельфи :)


 
jack128 ©   (2004-06-14 16:52) [6]


> не выводит

потому что "параметр задан не верно"


 
jack128 ©   (2004-06-14 16:54) [7]

var
DC: HDC;
S: string;
begin
DC:=Canvas.Handle;
S:=Memo1.Lines[0];
if DC <> Canvas.Handle then
  raise EXception.Create("Фигня вышла"); // Действительно фигня
if not TextOut(DC, 10, 10, PChar(s), Length(s)) then
  raiseLastWin32Error;
end;


 
Piter ©   (2004-06-14 17:00) [8]

jack128 (14.06.04 16:52) [6]

ты ровным счетом ничего не прояснил


 
Piter ©   (2004-06-14 17:03) [9]

Блин! Я в шоке... просто не понимаю...


 
DeadMeat ©   (2004-06-14 17:06) [10]

А если сделать так:
procedure TForm1.Button1Click(Sender: TObject);
var
DC: HDC;
S: string;
begin
DC:=Canvas.Handle;
S:=Memo1.Lines[0];
TextOut(Canvas.Handle, 10, 10, PChar(S), Length(S));
end;

То выводит...
Странно...

---
...Death Is Only The Begining...


 
DeadMeat ©   (2004-06-14 17:08) [11]

Пардон...
procedure TForm1.Button1Click(Sender: TObject);
var
DC: HDC;
S: string;
begin
S:=Memo1.Lines[0];
DC:=Canvas.Handle;
TextOut(Canvas.Handle, 10, 10, PChar(S), Length(S));
end;


---
...Death Is Only The Begining...


 
DeadMeat ©   (2004-06-14 17:09) [12]

Т.е. если смешать [1] с оригиналом во второй части (Во как загнул)... :))

---
...Death Is Only The Begining...


 
DiamondShark ©   (2004-06-14 17:13) [13]

Хм...

Если вместо
TextOut(DC, 10, 10, PChar(S), Length(S));
написать
Win32Check( TextOut(DC, 10, 10, PChar(S), Length(S)) );
то выбрасывается исключение.

Есть предположение, что где-то в глубине получения строки из мемо дц окна становится недействительным.


 
Piter ©   (2004-06-14 17:19) [14]

Я кое в чем разобрался.

Оказывается, при

S:=Memo1.Lines[0];

с какого-то фига Canvas.Handle увеличивается на единицу!
Иду копать VCL...


 
Piter ©   (2004-06-14 17:21) [15]

Ой, даже не то, что на единицу увеличивается, а вообще нафиг меняет свое значение


 
Piter ©   (2004-06-14 17:28) [16]

Понятно, короче... то есть, непонятно, но на самом деле Canvas.Handle постоянно меняет свое значение...
бросьте на форму TLabel и TTimer и напишите:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Label1.Caption := inttostr(Canvas.Handle);
end;


будете приятно удивлены... можно ничего не делать, просто смотреть на экран, где будут бежать цифирки :)


 
Piter ©   (2004-06-14 17:33) [17]

В общем, понятно. Смотрим на процедуру:

procedure TCustomForm.PaintWindow(DC: HDC);
begin
 FCanvas.Lock;
 try
   FCanvas.Handle := DC;
   try
     if FDesigner <> nil then FDesigner.PaintGrid else Paint;
   finally
     FCanvas.Handle := 0;
   end;
 finally
   FCanvas.Unlock;
 end;
end;


 
jack128 ©   (2004-06-14 17:39) [18]


> [17] Piter ©   (14.06.04 17:33)

не туда смотрим..

// s := Memo1.Lines[0]
function TMemoStrings.Get(Index: Integer): string;
var
 Text: array[0..4095] of Char;
begin
 Word((@Text)^) := SizeOf(Text);
 SetString(Result, Text, SendMessage(Memo.Handle, EM_GETLINE, Index,
   Longint(@Text)));
end;

а тперь смотрим на

procedure TWinControl.MainWndProc(var Message: TMessage);
begin
 try
   try
     WindowProc(Message);
   finally
     FreeDeviceContexts;      FreeMemoryContexts;
   end;
 except
   Application.HandleException(Self);
 end;
end;

теперь все контексты уничтожены.. в первом варианте DC := Canvas.HAndle - создает новый контекст..

А теперь вопрос знатокам: нафига после обработки каждого сообщения уничтожать все контексты??


 
DiamondShark ©   (2004-06-14 17:44) [19]


> А теперь вопрос знатокам: нафига после обработки каждого
> сообщения уничтожать все контексты??

Чтоб не утекали.


 
jack128 ©   (2004-06-14 17:47) [20]


> Чтоб не утекали.

в смысле? Куда они утекут? Просто мы будем их создовать не каждый раз, а один раз при создании окна и все. Или я чего то не понимаю? Я же не говорю, что их вообще не нужно уничтожать. Но не после же каждого сообщения...


 
Piter ©   (2004-06-14 17:58) [21]

jack128 (14.06.04 17:39) [18]
не туда смотрим..


туда я смотрю. Это ты не туда смотришь...

Все происходит так.

У TWinControl есть процедура:

WMPaint(var Message: TWMPaint); message WM_PAINT;

procedure TWinControl.WMPaint(var Message: TWMPaint);
var
 DC, MemDC: HDC;
 MemBitmap, OldBitmap: HBITMAP;
 PS: TPaintStruct;
begin
 if not FDoubleBuffered or (Message.DC <> 0) then
 begin
   if not (csCustomPaint in ControlState) and (ControlCount = 0) then
     inherited
   else
     PaintHandler(Message);
...............


Которая как видно вызывает PaintHandler

procedure TWinControl.PaintHandler(var Message: TWMPaint);
var
 I, Clip, SaveIndex: Integer;
 DC: HDC;
 PS: TPaintStruct;
begin
 DC := Message.DC;
 if DC = 0 then DC := BeginPaint(Handle, PS);
 try
   if FControls = nil then PaintWindow(DC) else
.....................


А эта вызывает PaintWindow:

procedure TCustomForm.PaintWindow(DC: HDC);
begin
 FCanvas.Lock;
 try
   FCanvas.Handle := DC;
   try
     if FDesigner <> nil then FDesigner.PaintGrid else Paint;
   finally
     FCanvas.Handle := 0;
   end;
 finally
   FCanvas.Unlock;
 end;
end;


Каждый раз при WM_PAINT Canvas.Handle меняется...


 
jack128 ©   (2004-06-14 18:04) [22]


> Каждый раз при WM_PAINT Canvas.Handle меняется...

в какой строчке из этих двух

>  DC:=Canvas.Handle;
>  S:=Memo1.Lines[0];

посылается wm_paint? Причем не через InvalidateXXX, а через UpdateWindow !!!


 
Piter ©   (2004-06-14 18:12) [23]

в первом варианте DC := Canvas.HAndle - создает новый контекст

да, согласен. Немного проглючил


 
D7 (autor)   (2004-06-14 18:54) [24]

А если вставить такую строчку, то текст выводится (DC не изменяется):

procedure TForm1.Button1Click(Sender: TObject);
var
DC: HDC;
S: string;
begin
DC:=Canvas.Handle;
S:=Memo1.Lines[0];
if DC=Canvas.Handle then
  TextOut(DC, 10, 10, PChar(S), Length(S));
end;


 
Piter ©   (2004-06-14 18:57) [25]

ну естественно, ведь вызывается Canvas.Handle

Уже писали:

Canvas.Handle - создает новый контекст


 
D7 (autor)   (2004-06-14 19:01) [26]

Что-то не понял: контекст новый, а DC - старый?


 
Плохиш ©   (2004-06-14 19:05) [27]

А чем Canvas.TextOut не устраивает?


 
D7 (autor)   (2004-06-14 19:07) [28]

2 Плохиш
См. ответ [2]


 
jack128 ©   (2004-06-14 19:08) [29]


> [24] D7 (autor)   (14.06.04 18:54)

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


 
D7 (autor)   (2004-06-14 19:14) [30]

> jack128 ©   (14.06.04 19:08) [29]

А где непосредственно перед выделенной строчкой находится (или наоборот куда исчезает первоначальный контекст, причем с тем же HDC)


 
jack128 ©   (2004-06-14 19:24) [31]


> А где непосредственно перед выделенной строчкой находится
> (или наоборот куда исчезает первоначальный контекст, причем
> с тем же HDC)

в строке s := Memo1.Lines[0];
см > [18] jack128 ©   (14.06.04 17:39)


 
D7 (autor)   (2004-06-14 19:49) [32]

> jack128 ©
Ну что-же, уговорил...
Как говорится - спасибо за внимание.



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.034 c
14-1087387192
osama
2004-06-16 15:59
2004.07.04
что слушаем


6-1084215582
AndersoNRules
2004-05-10 22:59
2004.07.04
TIdTCPClient vs TSocketClient


3-1086605578
Борис_4
2004-06-07 14:52
2004.07.04
Не работает BDE c Access97 в Delphi 5 на новом компьютере


1-1087801439
Lion
2004-06-21 11:03
2004.07.04
Прерывания


3-1086788169
Stupid
2004-06-09 17:36
2004.07.04
Как в DBGrid узнать ширину V_Scrolla и колонки что до полей?