![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос про GetDC [D6]
Суслик © (2005-09-02 19:01:00)Есть следующая подпрограмма:
function GetMaxStringsWidth(const aFont: TFont;
const aStrs: array of String): Integer;
var
kDC: HDC;
kCanvas: TCanvas;
begin
kDC := GetDC(0);
try
kCanvas := TCanvas.Create();
try
kCanvas.Handle := kDC;
kCanvas.Font := aFont;
Result := 0;
for kI := 0 to High(aStrs) do
begin
kW := kCanvas.TextWidth(aStrs[kI]);
if kW > Result then
Result := kW;
end
finally
kCanvas.Free();
end;
finally
ReleaseDC(0, kDC);
end;
end;
Есть ли что-то некорректное в таком использовании DC мимо VCL?
Игорь Шевченко (2005-09-08 11:14:00) [1]
> finally
> kCanvas.Free();
> end;
finally
kCanvas.Handle := 0;
kCanvas.Free();
end;
Суслик (2005-09-06 14:40:00) [2]up :)
Суслик (2005-09-04 10:48:00) [3]В действительности исходный код из моего проекта. Работает не первый год.
Сейчас я провожу модернизацию проекта (переход на runtime пакеты). В связи с этим пересматриваю все библиотеки общего назначения. В том числе и указанный код. Он достался мне в наследство еще давно-давно.
Я совсем не разбираюсь в DC на уровне WinApi, а тем более в комбинацииWinApi+VCL в области DC. Поэтому весь такой код, да еще и писанный не мной, у меня вызывает опасения.
Просветите, кто точно знает :)
Турист (2005-09-03 18:13:00) [4]>MBo © (03.09.05 17:41) [2]
procedure TForm1.Button1Click(Sender: TObject);
var
kDC: HDC;
kCanvas: TCanvas;
CurrentBrush, CurrentPen, CurrentFont: HGDIOBJ;
SaveIndex: Integer;
begin
kDC := GetDC(0);
try
// SaveIndex := SaveDC(kDC);
try
CurrentBrush := GetCurrentObject(kDC, OBJ_BRUSH);
CurrentPen := GetCurrentObject(kDC, OBJ_PEN);
CurrentFont := GetCurrentObject(kDC, OBJ_FONT);
kCanvas := TCanvas.Create();
try
kCanvas.Handle := kDC;
kCanvas.Font := Font;
ShowMessage(IntToStr(kCanvas.TextWidth('123')))
finally
kCanvas.Free
end;
finally
// RestoreDC(kDC, SaveIndex)
end;
if CurrentBrush = GetCurrentObject(kDC, OBJ_BRUSH) then
ShowMessage('Brush OK')
else
ShowMessage('Brush Fail');
if CurrentPen = GetCurrentObject(kDC, OBJ_PEN) then
ShowMessage('Pen OK')
else
ShowMessage('Pen Fail');
if CurrentFont = GetCurrentObject(kDC, OBJ_FONT) then
ShowMessage('Font OK')
else
ShowMessage('Font Fail')
finally
ReleaseDC(0, kDC)
end
end;
Турист (2005-09-03 17:50:00) [5]>MBo © (03.09.05 17:41) [2]
Думаете SaveDC, RestoreDC не нужны ?
MBo (2005-09-03 17:41:00) [6]>т.е. "испортятся" старые Pen, Brush, Font
неа...
При GetDC в полученном контексте они стоят по умолчанию, так что портить особо нечего
Турист (2005-09-03 10:33:00) [7]>Суслик © (02.09.05 19:01)
В общем случае, наверно, некорректно. Пара необъявленных переменных, при уничтожении TCanvas VCL выполнит TCanvas.DeselectHandles;
...
SelectObject(FHandle, StockPen);
SelectObject(FHandle, StockBrush);
SelectObject(FHandle, StockFont);
...
т.е. "испортятся" старые Pen, Brush, Font
Пример из Forms.pas,
...
Canvas := TControlCanvas.Create;
with Canvas do
try
SaveIndex := SaveDC(hDC);
try
Handle := hDC;
Font := Screen.MenuFont;
Menus.DrawMenuItem(MenuItem, Canvas, rcItem,
TOwnerDrawState(LongRec(itemState).Lo));
finally
Handle := 0;
RestoreDC(hDC, SaveIndex)
end;
finally
Free;
end;
...