Форум: "Потрепаться";
Текущий архив: 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