-
у меня есть некие HGDIOBJ объекты. по идее вопрос для всех подтипов, но конкретно сейчас вожусь с HBITMAP. как мне проверить существует ли этот объект? думал GetObjectType выдаст ошибку, если объект не существует - оказалост фиг, возвращает верную константу. ковыряюсь в MSDN, но пока не нахожу нужного. попытаться что ли GetObject вызвать? но мне же для любого типа надо и просто узнать не был ли он уже удалён.
-
немного поясню - объекту делается DeleteObject. по идее он после этого больше не существует:
>> После того, как объект удаляется, его дескриптор более не допустим.
ну и вот как же имея только дескриптор узнать допустим он в данный момент или уже нет?
-
Никак, технически он валиден всегда
-
-
не ведал я об блоге сиём, дюже любопытно в ём... то есть я сделал DeleteObject(HBITMAP), но он остался валиден? во дела... дак может тогда их можно вовсе не удалять никогда? или можно по пять раз подряд "удалять" и это не будет ошибкой? тогда такой вопрос - сделал я DeleteObject(HDC), а в нём был HBITMAP выбран - он удалился? выходит не проверить это? так надо или не надо делать DeleteObject для такого битмапа? в MSDN как-то размыто написано. и ещё Вам в коллекцию, вдруг не встречали этот финт (D7, Win7): procedure TForm1.Button1Click(Sender: TObject);
begin
Repaint;
DrawCaption(Handle, Canvas.Handle, Rect(10, 10, 800, 40), DC_ACTIVE Or DC_TEXT Or DC_ICON Or DC_GRADIENT);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Repaint;
Canvas.Lock;
DrawCaption(Handle, Canvas.Handle, Rect(10, 50, 800, 80), DC_ACTIVE Or DC_TEXT Or DC_ICON Or DC_GRADIENT);
Canvas.Unlock;
end;
procedure TForm1.Button3Click(Sender: TObject);
var dc: HDC;
begin
Repaint;
dc:=GetDC(Handle);
DrawCaption(Handle, dc, Rect(10, 90, 800, 120), DC_ACTIVE Or DC_TEXT Or DC_ICON Or DC_GRADIENT);
ReleaseDC(Handle, dc);
end;
-
Нет, удалять нужно - обязательно (ибо счетчик), но т.к. это глобальная вещь то ее можно нехитрым образом и оживить.
По поводу кода - пока лениво смотреть, после новогодних гляну что там такое.
-
Посмотрел, ну в принципе нюанс красивый, причину сможешь понять если посмотришь к какому DC привязан первый вызов
-
Может DrawCaption это типа макроса или обёртки? Просто вызывает TextOut, GradientFill и прочее? А между ними DC успевает разрушиться как описано по ссылке?
> сделал я DeleteObject(HDC), а в нём был HBITMAP выбран - он удалился?
гм... А в доках вовсе не написано чтоб DeleteObject принимал контекст. Может вы спутали с DeleteDC? Зато написано что освобождаются все системные ресурсы связанные с удаляемым объектом. Так что если битмап был в DC - возможно что не нужно удалять. Но явно не написано.
> (ибо счетчик)
Просто любопытно - а до этого счётчика добраться возможно? Посмотреть какое там значение? И если ноль - то дескриптор таки точно не валиден. =)
-
Да, конечно возможно, любой хэндл это указатель на структуру
-
Поковырял ещё этот MSDN, короче вообще нельзя DeleteObject(HDC) делать. Раз "технически он валиден всегда" - то не проверишь удаляется ли он той функцией или нет, но документация указывает что надо делать только через DeleteDC(HDC). А вот удаляются ли всякие перья, кисти, шрифты, битмапы, регионы, палитры - которые были в удаляемом HDC - чтот не нашёл.
> если посмотришь к какому DC привязан первый вызов
гм... Сейчас перечитал это ещё два раза и понял что не понял что именно подразумевалось... "Привязан" это что? Как это "смотреть"? Поясните?
> Да, конечно возможно, любой хэндл это указатель на структуру
ммм) А примерчика под рукой не завалялось случайно?
-
-
-
Громовержец (05.01.16 23:07)
Программу нормально писать не предлагать ? До чего только народ не доходит в своих попытках гланды вырезать.
-
ой, ой. точно, спасибо!
почему? есть же функция IsWindow() и ею пользуются. и это нормально и правильно. почему вам кажется странным моё ожидание такой же только для HGDIOBJ?
-
-
Если хандлы создаются в процессе работы функции рисования, они там же и должны быть прибиты через DeleteObject. Если они вдруг становятся глобальными - для них существуют классы-оболочки, которые сами следят за валидностью хандла.
|