Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > "Аномалия" с ico->Width


Автор: artsb 22.6.2008, 20:03
Всем привет!

Вот кусок кода:
Код

TIcon* ico;
//---------------------------------------------------------------------------
void __fastcall TfMain::FormCreate(TObject *Sender)
{
ico=new TIcon();
ico->LoadFromFile("my_icon.ico");
}
//---------------------------------------------------------------------------
void __fastcall TfMain::FormPaint(TObject *Sender)
{
int k=(80-ico->Width)/2;
Canvas->Draw(k,k,ico);
}


Проблема в том, что при первой отрисовке ico->Width=32 не зависимо от реального размера иконки и, естественно, при появлении окна иконка отображается не на своём месте. При последующих отрисовках - размер правильный.
В чём может быть проблема?
Спасибо.

Автор: Rrader 23.6.2008, 07:38
artsb, это связано со спецификой класса TIcon smile Допустим, твоя иконка имеет размер 16х16.

Вот код получения ширины:
Код

int __fastcall TIcon::GetWidth(void)
{
    return (FImage->FSize->X ? FImage->FSize->X : GetSystemMetrics(SM_CXICON));
}

GetSystemMetrics(SM_CXICON) возвращает 32 (по умолчанию). При создании TIcon поле FImage инициализируется нулями, т.е. FSize->X == 0; FSize->Y == 0;
Соответственно возращается 32. При вызове Canvas->Draw() в данном случае вызывается метод TIcon->Draw() и происходит следующее: вызывается функция (ACanvas - это Canvas формы в данном случае):
Код

DrawIconEx(ACanvas->FHandle, X, Y, Handle, 0, 0, 0, 0, DI_NORMAL);

При обращении к свойству Handle запрашивается дескриптор иконки:
Код

HICON __fastcall TIcon::GetHandle(void)
{
    HandleNeeded();
    return FImage->FHandle;
}

В процедуре HandleNeeded() вызывается функция ReadIcon. Она довольно объёмная, в ней сначала тоже происходит вызов GetSystemMetrics(SM_CXICON), но потом значение берется из массива указателей на структуру TIconRec. Там проводятся предварительные расчеты (в функции BetterSize), и мы получаем 16х16 smile Они запоминаются в FImage->FSize и потом уже нормально возвращаются через GetWidth() и GetHeight()

Автор: artsb 23.6.2008, 18:41
Rrader, спасибо!

Но, вообще, странно, ведь я после создания объекта TIcon загружаю в него иконку. Размер не изменяется?

Автор: Rrader 24.6.2008, 14:22
Нет. Не сразу smile 

Автор: artsb 24.6.2008, 21:08
Спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)