Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.035 c
14-1087148884
zokzok
2004-06-13 21:48
2004.07.04
Сколько времени в день можно работать компьютеру


6-1084020603
serg_kr
2004-05-08 16:50
2004.07.04
FTP в Delphi 8


6-1084352553
Ivolg
2004-05-12 13:02
2004.07.04
Данные


14-1086982998
Александр
2004-06-11 23:43
2004.07.04
Где взять историческую српавку по Delphi?


6-1083941339
BVV
2004-05-07 18:48
2004.07.04
функции переводящая IP-строку в IP-число





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский